Skip to content

Commit

Permalink
Neat 103 ontology2rules step missing (#413)
Browse files Browse the repository at this point in the history
* update of UI and new step added

* bump version added changelog
  • Loading branch information
nikokaoja committed Apr 24, 2024
1 parent 3b22e12 commit 324e4c9
Show file tree
Hide file tree
Showing 15 changed files with 178 additions and 69 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.PHONY: run-explorer run-tests run-linters build-ui build-python build-docker run-docker compose-up

version="0.75.3"
version="0.75.4"
run-explorer:
@echo "Running explorer API server..."
# open "http://localhost:8000/static/index.html" || true
Expand Down
2 changes: 1 addition & 1 deletion cognite/neat/_version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.75.3"
__version__ = "0.75.4"
2 changes: 1 addition & 1 deletion cognite/neat/app/api/routers/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ async def convert_data_model_to_rules(file: UploadFile):

# load as OWL
elif suffix in [".ttl", ".owl"]:
rules, issues = importers.OWLImporter(owl_filepath=temp_filepath).to_rules(role=RoleTypes.dms_architect)
rules, issues = importers.OWLImporter(filepath=temp_filepath).to_rules(role=RoleTypes.dms_architect)

# load as YAML
elif suffix in [".yml", ".yaml"]:
Expand Down
6 changes: 3 additions & 3 deletions cognite/neat/app/ui/neat-app/build/asset-manifest.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"files": {
"main.css": "./static/css/main.38a62222.css",
"main.js": "./static/js/main.25d27396.js",
"main.js": "./static/js/main.4345d42f.js",
"static/media/logo.svg": "./static/media/logo.8093b84df9ed36a174c629d6fe0b730d.svg",
"index.html": "./index.html",
"main.38a62222.css.map": "./static/css/main.38a62222.css.map",
"main.25d27396.js.map": "./static/js/main.25d27396.js.map"
"main.4345d42f.js.map": "./static/js/main.4345d42f.js.map"
},
"entrypoints": [
"static/css/main.38a62222.css",
"static/js/main.25d27396.js"
"static/js/main.4345d42f.js"
]
}
2 changes: 1 addition & 1 deletion cognite/neat/app/ui/neat-app/build/index.html
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./logo192.png"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="NEAT controll panel"/><link rel="apple-touch-icon" href="./logo192.png"/><link rel="manifest" href="./manifest.json"/><title>NEAT App</title><script defer="defer" src="./static/js/main.25d27396.js"></script><link href="./static/css/main.38a62222.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="./logo192.png"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="NEAT controll panel"/><link rel="apple-touch-icon" href="./logo192.png"/><link rel="manifest" href="./manifest.json"/><title>NEAT App</title><script defer="defer" src="./static/js/main.4345d42f.js"></script><link href="./static/css/main.38a62222.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>

Large diffs are not rendered by default.

Large diffs are not rendered by default.

129 changes: 77 additions & 52 deletions cognite/neat/app/ui/neat-app/src/components/RulesV2Viewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,72 @@ import { Alert, AlertTitle, Button, Tab, Tabs, ToggleButton, ToggleButtonGroup }
import { Image } from '@mui/icons-material';
import InformationArchitectDataModelEditor from './RulesV2Editor';

function MetadataTable(props: any) {
function InformationMetadataTable(props: any) {
const metadata = props.metadata;
return (
<Box sx={{marginTop:5}}>
<TableContainer component={Paper}>
<Table aria-label="metadata table">
<TableBody>
<TableRow>
<TableCell><b>Title</b></TableCell>
<TableCell>{metadata?.name}</TableCell>
</TableRow>
<TableRow>
<TableCell><b>Role</b></TableCell>
<TableCell>{metadata?.role}</TableCell>
</TableRow>
<TableRow>
<TableCell><b>Schema state</b></TableCell>
<TableCell>{metadata?.schema_}</TableCell>
</TableRow>
<TableRow>
<TableCell><b>Extension</b></TableCell>
<TableCell>{metadata?.extension}</TableCell>
</TableRow>
<TableRow>
<TableCell><b>Description</b></TableCell>
<TableCell>{metadata?.description}</TableCell>
</TableRow>
<TableRow>
<TableCell><b>Namespace</b></TableCell>
<TableCell>{metadata?.namespace}</TableCell>
</TableRow>
<TableRow>
<TableCell><b>Prefix</b></TableCell>
<TableCell>{metadata?.prefix}</TableCell>
</TableRow>
<TableRow>
<TableCell><b>Version</b></TableCell>
<TableCell>{metadata?.version}</TableCell>
</TableRow>
<TableRow>
<TableCell><b>Created at</b></TableCell>
<TableCell>{metadata?.created}</TableCell>
</TableRow>
<TableRow>
<TableCell><b>Updated at</b></TableCell>
<TableCell>{metadata?.updated}</TableCell>
</TableRow>
<TableRow>
<TableCell><b>Creator</b></TableCell>
<TableCell>{metadata?.creator}</TableCell>
</TableRow>
<TableRow>
<TableCell><b>License</b></TableCell>
<TableCell>{metadata?.license}</TableCell>
</TableRow>
<TableRow>
<TableCell><b>Rights</b></TableCell>
<TableCell>{metadata?.rights}</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
</Box>
);
}
function DmsMetadataTable(props: any) {
const metadata = props.metadata;
return (
<Box sx={{marginTop:5}}>
Expand Down Expand Up @@ -51,6 +116,10 @@ function MetadataTable(props: any) {
<TableCell><b>DMS Space</b></TableCell>
<TableCell>{metadata?.space}</TableCell>
</TableRow>
<TableRow>
<TableCell><b>External ID</b></TableCell>
<TableCell>{metadata?.external_id}</TableCell>
</TableRow>
<TableRow>
<TableCell><b>Version</b></TableCell>
<TableCell>{metadata?.version}</TableCell>
Expand All @@ -74,35 +143,6 @@ function MetadataTable(props: any) {
);
}

/*
Class:
{
"class_": "Sourceable",
"name": null,
"description": null,
"parent": null,
"reference": null,
"match_type": null,
"comment": null
},
Property:
{
"class_": "Asset",
"name": null,
"description": null,
"property_": "Systemstatus",
"value_type": "string",
"min_count": 1,
"max_count": 1,
"default": null,
"reference": null,
"match_type": null,
"rule_type": null,
"rule": null,
"comment": null
},
*/

function InformationArchitectPropsRow(props: { row: any,properties: any,onEditClick: any}) {
const { row,properties } = props;
Expand Down Expand Up @@ -182,26 +222,7 @@ function InformationArchitectPropsRow(props: { row: any,properties: any,onEditCl
</React.Fragment>
);
}
/*
{
"class_": "CurrentLimit",
"name": null,
"description": null,
"property_": "CurrentLimit_value",
"relation": null,
"value_type": "text",
"nullable": false,
"is_list": false,
"default": null,
"reference": null,
"container": "CurrentLimit",
"container_property": "CurrentLimit_value",
"view": "CurrentLimit",
"view_property": "CurrentLimit_value",
"index": null,
"constraint": null
},
*/


function DMSArchitectPropsRow(props: { row: any,properties: any,views: any}) {
const { row,properties,views } = props;
Expand Down Expand Up @@ -555,8 +576,9 @@ export default function RulesV2Viewer(props: any) {
<AlertTitle>Warning</AlertTitle>
{alertMsg}
</Alert> )}
{selectedTab === 0 && rules.metadata && (
<MetadataTable metadata={rules.metadata} />

{selectedTab === 0 && role == "information architect" && (
<InformationMetadataTable metadata={rules.metadata} />
)}

{selectedTab == 1 && role == "information architect" && (
Expand Down Expand Up @@ -607,6 +629,9 @@ export default function RulesV2Viewer(props: any) {
</Table>
</TableContainer>
)}
{selectedTab === 0 && role == "DMS Architect" && (
<DmsMetadataTable metadata={rules.metadata} />
)}
{selectedTab == 1 && role == "DMS Architect" && (
<TableContainer component={Paper}>
<Table aria-label="collapsible table">
Expand Down
4 changes: 2 additions & 2 deletions cognite/neat/rules/importers/_owl2rules/_owl2rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ class OWLImporter(BaseImporter):
"""

def __init__(self, owl_filepath: Path, make_compliant: bool = False):
self.owl_filepath = owl_filepath
def __init__(self, filepath: Path, make_compliant: bool = False):
self.owl_filepath = filepath
self.make_compliant = make_compliant

@overload
Expand Down
80 changes: 80 additions & 0 deletions cognite/neat/workflows/steps/lib/rules_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

__all__ = [
"ExcelToRules",
"OntologyToRules",
"DMSToRules",
]

Expand Down Expand Up @@ -90,6 +91,85 @@ def run(self, flow_message: FlowMessage) -> (FlowMessage, MultiRuleData): # typ
return FlowMessage(output_text=output_text), MultiRuleData.from_rules(rules)


class OntologyToRules(Step):
"""This step import rules from the ontology file (owl) and validates it."""

description = "This step imports rules from an ontology file "
version = "private-beta"
category = CATEGORY
configurables: ClassVar[list[Configurable]] = [
Configurable(
name="File name",
value="",
label="Full file name of the ontology file in the rules folder. \
If not provided, step will attempt to get file name from payload \
of 'File Uploader' step (if exist)",
),
Configurable(
name="Report formatter",
value=next(iter(FORMATTER_BY_NAME.keys())),
label="The format of the report for the validation of the rules",
options=list(FORMATTER_BY_NAME),
),
Configurable(
name="Role",
value="infer",
label="For what role Rules are intended?",
options=["infer", *RoleTypes.__members__.keys()],
),
Configurable(
name="Make compliant",
value="True",
label=(
"Attempt to make the imported Rules compliant, by converting "
"the information model provided in the ontology to data model."
),
options=["True", "False"],
),
]

def run(self, flow_message: FlowMessage) -> (FlowMessage, MultiRuleData): # type: ignore[syntax, override]
if self.configs is None or self.data_store_path is None:
raise StepNotInitialized(type(self).__name__)

file_name = self.configs.get("File name", None)
full_path = flow_message.payload.get("full_path", None) if flow_message.payload else None
make_compliant = self.configs.get("Make compliant", "True") == "True"

if file_name:
rules_file_path = Path(self.data_store_path) / "rules" / file_name
elif full_path:
rules_file_path = full_path
else:
error_text = "Expected either 'File name' in the step config or 'File uploader' step uploading Excel Rules."
return FlowMessage(error_text=error_text, step_execution_status=StepExecutionStatus.ABORT_AND_FAIL)

# if role is None, it will be inferred from the rules file
role = self.configs.get("Role")
role_enum = None
if role != "infer" and role is not None:
role_enum = RoleTypes[role]

ontology_importer = importers.OWLImporter(filepath=rules_file_path, make_compliant=make_compliant)
rules, issues = ontology_importer.to_rules(role=role_enum, errors="continue")

if rules is None:
output_dir = self.data_store_path / Path("staging")
report_writer = FORMATTER_BY_NAME[self.configs["Report formatter"]]()
report_writer.write_to_file(issues, file_or_dir_path=output_dir)
report_file = report_writer.default_file_name
error_text = (
"<p></p>"
f'<a href="/data/staging/{report_file}?{time.time()}" '
f'target="_blank">Failed to validate rules, click here for report</a>'
)
return FlowMessage(error_text=error_text, step_execution_status=StepExecutionStatus.ABORT_AND_FAIL)

output_text = "Rules validation passed successfully!"

return FlowMessage(output_text=output_text), MultiRuleData.from_rules(rules)


class DMSToRules(Step):
"""This step imports rules from CDF Data Model"""

Expand Down
6 changes: 6 additions & 0 deletions docs/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ Changes are grouped as follows:
- `Fixed` for any bug fixes.
- `Security` in case of vulnerabilities.

## [0.75.4] - 24-05-24
### Fixed
- Rendering of correct metadata in UI for information architect
### Added
- Added `OntologyToRules` that works with V2 Rules (profiling)

## [0.75.3] - 23-05-24
### Fixed
- Names and descriptions were not considered for views and view properties
Expand Down
Binary file not shown.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "cognite-neat"
version = "0.75.3"
version = "0.75.4"
readme = "README.md"
description = "Knowledge graph transformation"
authors = [
Expand Down
4 changes: 1 addition & 3 deletions tests/tests_unit/rules/test_importers/test_owl_importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@


def test_owl_importer():
rules, _ = importers.OWLImporter(
owl_filepath="https://data.nobelprize.org/terms.rdf", make_compliant=True
).to_rules()
rules, _ = importers.OWLImporter(filepath="https://data.nobelprize.org/terms.rdf", make_compliant=True).to_rules()

assert len(rules.classes) == 11
assert len(rules.properties) == 16
Expand Down

0 comments on commit 324e4c9

Please sign in to comment.