Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(xmlvalidate): add save graph flag to CLI (DEV-4206) #1199

Merged
merged 9 commits into from
Oct 5, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
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
4 changes: 3 additions & 1 deletion src/dsp_tools/cli/call_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,9 @@ def _call_xmlupload(args: argparse.Namespace) -> bool:


def _call_xml_validate(args: argparse.Namespace) -> bool:
return xml_validate(filepath=Path(args.xmlfile), api_url=args.server, dev_route=args.dev)
return xml_validate(
filepath=Path(args.xmlfile), api_url=args.server, dev_route=args.dev, save_graphs=args.save_graphs
)


def _call_resume_xmlupload(args: argparse.Namespace) -> bool:
Expand Down
3 changes: 3 additions & 0 deletions src/dsp_tools/cli/create_parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,9 @@ def _add_xml_validate(
"-s", "--server", default=default_dsp_api_url, help="URL of the DSP server where DSP-TOOLS sends the data to"
)
subparser.add_argument("--dev", action="store_true", help="Validate with experimental features.")
subparser.add_argument(
"--save-graphs", action="store_true", help="Save the data, onto and shacl graph as ttl files."
)


def _add_resume_xmlupload(
Expand Down
22 changes: 21 additions & 1 deletion src/dsp_tools/commands/xml_validate/xml_validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,15 @@
LIST_SEPARATOR = "\n - "


def xml_validate(filepath: Path, api_url: str, dev_route: bool) -> bool: # noqa: ARG001 (unused argument)
def xml_validate(filepath: Path, api_url: str, dev_route: bool, save_graphs: bool) -> bool: # noqa: ARG001 (unused argument)
"""
Takes a file and project information and validates it against the ontologies on the server.

Args:
filepath: path to the xml data file
api_url: url of the api host
dev_route: if this flag is set features that are still in development will be used
save_graphs: if this flag is set, all the graphs will be saved in a folder

Returns:
true unless it crashed
Expand All @@ -42,9 +43,14 @@ def xml_validate(filepath: Path, api_url: str, dev_route: bool) -> bool: # noqa
onto_con = OntologyConnection(api_url, shortcode)
ontologies, shapes = _get_shacl(onto_con)
data_graph = data_rdf.make_graph()
generic_filepath = Path()
if save_graphs:
generic_filepath = _save_graph(filepath, ontologies, shapes, data_graph)
# data_graph += ontologies
val = ShaclValidator(api_url)
report = _validate(val, shapes, data_graph)
if save_graphs:
Nora-Olivia-Ammann marked this conversation as resolved.
Show resolved Hide resolved
report.validation_graph.serialize(f"{generic_filepath}_VALIDATION_REPORT.ttl")
if report.conforms:
cprint("\n Validation passed! ", color="green", attrs=["bold", "reverse"])
else:
Expand All @@ -70,6 +76,20 @@ def _inform_about_experimental_feature() -> None:
warnings.warn(DspToolsUserWarning(LIST_SEPARATOR.join(what_is_validated)))


def _save_graph(filepath: Path, onto: Graph, shacl: Graph, data: Graph) -> Path:
parent_directory = filepath.parent
new_directory = parent_directory / "graphs"
new_directory.mkdir(exist_ok=True)
cprint(f"\n Saving graphs to {new_directory} ", color="light_blue", attrs=["bold", "reverse"])
generic_filepath = new_directory / filepath.stem
onto.serialize(f"{generic_filepath}_ONTO.ttl")
shacl.serialize(f"{generic_filepath}_SHACL.ttl")
data.serialize(f"{generic_filepath}_DATA.ttl")
onto_data = onto + data
onto_data.serialize(f"{generic_filepath}_ONTO_DATA.ttl")
return generic_filepath


def _validate(validator: ShaclValidator, shapes_graph: Graph, data_graph: Graph) -> ValidationReport:
shape_str = shapes_graph.serialize(format="ttl")
data_str = data_graph.serialize(format="ttl")
Expand Down
22 changes: 19 additions & 3 deletions test/unittests/cli/test_cli_with_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,23 +144,39 @@ def test_xml_validate_default(xml_validate: Mock) -> None:
file = "filename.xml"
args = f"xml-validate {file}".split()
entry_point.run(args)
xml_validate.assert_called_once_with(filepath=Path(file), api_url="http://0.0.0.0:3333", dev_route=False)
xml_validate.assert_called_once_with(
filepath=Path(file), api_url="http://0.0.0.0:3333", dev_route=False, save_graphs=False
)


@patch("dsp_tools.cli.call_action.xml_validate")
def test_xml_validate_dev(xml_validate: Mock) -> None:
file = "filename.xml"
args = f"xml-validate {file} --dev".split()
entry_point.run(args)
xml_validate.assert_called_once_with(filepath=Path(file), api_url="http://0.0.0.0:3333", dev_route=True)
xml_validate.assert_called_once_with(
filepath=Path(file), api_url="http://0.0.0.0:3333", dev_route=True, save_graphs=False
)


@patch("dsp_tools.cli.call_action.xml_validate")
def test_xml_validate_save_graph(xml_validate: Mock) -> None:
file = "filename.xml"
args = f"xml-validate {file} --save-graphs".split()
entry_point.run(args)
xml_validate.assert_called_once_with(
filepath=Path(file), api_url="http://0.0.0.0:3333", dev_route=False, save_graphs=True
)


@patch("dsp_tools.cli.call_action.xml_validate")
def test_xml_validate_other_server(xml_validate: Mock) -> None:
file = "filename.xml"
args = f"xml-validate {file} -s https://api.dasch.swiss".split()
entry_point.run(args)
xml_validate.assert_called_once_with(filepath=Path(file), api_url="https://api.dasch.swiss", dev_route=False)
xml_validate.assert_called_once_with(
filepath=Path(file), api_url="https://api.dasch.swiss", dev_route=False, save_graphs=False
)


@patch("dsp_tools.cli.call_action.resume_xmlupload")
Expand Down