dsp-tools 17.0.0.post10__py3-none-any.whl → 17.0.0.post21__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of dsp-tools might be problematic. Click here for more details.
- dsp_tools/cli/call_action.py +68 -25
- dsp_tools/clients/metadata_client.py +24 -0
- dsp_tools/clients/metadata_client_live.py +42 -0
- dsp_tools/clients/ontology_client.py +21 -0
- dsp_tools/clients/ontology_client_live.py +139 -0
- dsp_tools/commands/create/__init__.py +0 -0
- dsp_tools/commands/create/communicate_problems.py +19 -0
- dsp_tools/commands/create/constants.py +7 -0
- dsp_tools/commands/create/create_on_server/__init__.py +0 -0
- dsp_tools/commands/create/create_on_server/cardinalities.py +121 -0
- dsp_tools/commands/create/create_on_server/mappers.py +12 -0
- dsp_tools/commands/create/models/__init__.py +0 -0
- dsp_tools/commands/create/models/input_problems.py +32 -0
- dsp_tools/commands/create/models/parsed_ontology.py +48 -0
- dsp_tools/commands/create/models/parsed_project.py +49 -0
- dsp_tools/commands/create/models/rdf_ontology.py +19 -0
- dsp_tools/commands/create/models/server_project_info.py +25 -0
- dsp_tools/commands/create/parsing/__init__.py +0 -0
- dsp_tools/commands/create/parsing/parse_ontology.py +108 -0
- dsp_tools/commands/create/parsing/parse_project.py +99 -0
- dsp_tools/commands/create/parsing/parsing_utils.py +43 -0
- dsp_tools/commands/create/serialisation/__init__.py +0 -0
- dsp_tools/commands/create/serialisation/ontology.py +41 -0
- dsp_tools/commands/project/create/project_create_all.py +35 -25
- dsp_tools/commands/project/create/project_create_ontologies.py +39 -89
- dsp_tools/commands/project/legacy_models/resourceclass.py +0 -33
- dsp_tools/error/exceptions.py +16 -0
- dsp_tools/utils/data_formats/iri_util.py +7 -0
- dsp_tools/utils/rdflib_utils.py +10 -0
- {dsp_tools-17.0.0.post10.dist-info → dsp_tools-17.0.0.post21.dist-info}/METADATA +1 -1
- {dsp_tools-17.0.0.post10.dist-info → dsp_tools-17.0.0.post21.dist-info}/RECORD +33 -10
- {dsp_tools-17.0.0.post10.dist-info → dsp_tools-17.0.0.post21.dist-info}/WHEEL +1 -1
- {dsp_tools-17.0.0.post10.dist-info → dsp_tools-17.0.0.post21.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
from dsp_tools.commands.create.models.parsed_ontology import ParsedOntology
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass
|
|
10
|
+
class ParsedProject:
|
|
11
|
+
prefixes: dict[str, str]
|
|
12
|
+
project_metadata: ParsedProjectMetadata
|
|
13
|
+
permissions: ParsedPermissions
|
|
14
|
+
groups: list[ParsedGroup]
|
|
15
|
+
users: list[ParsedUser]
|
|
16
|
+
lists: list[ParsedList]
|
|
17
|
+
ontologies: list[ParsedOntology]
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass
|
|
21
|
+
class ParsedProjectMetadata:
|
|
22
|
+
shortcode: str
|
|
23
|
+
shortname: str
|
|
24
|
+
longname: str
|
|
25
|
+
descriptions: dict[str, str]
|
|
26
|
+
keywords: list[str]
|
|
27
|
+
enabled_licenses: list[str]
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@dataclass
|
|
31
|
+
class ParsedPermissions:
|
|
32
|
+
default_permissions: str
|
|
33
|
+
default_permissions_overrule: dict[str, Any] | None
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass
|
|
37
|
+
class ParsedGroup:
|
|
38
|
+
info: dict[str, Any]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass
|
|
42
|
+
class ParsedUser:
|
|
43
|
+
info: dict[str, Any]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass
|
|
47
|
+
class ParsedList:
|
|
48
|
+
name: str
|
|
49
|
+
info: dict[str, Any]
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
from rdflib import Literal
|
|
6
|
+
from rdflib import URIRef
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass
|
|
10
|
+
class RdfResourceCardinality:
|
|
11
|
+
resource_iri: URIRef
|
|
12
|
+
on_property: URIRef
|
|
13
|
+
cardinality: RdfCardinalityRestriction
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass
|
|
17
|
+
class RdfCardinalityRestriction:
|
|
18
|
+
owl_property: URIRef
|
|
19
|
+
cardinality_value: Literal
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from dataclasses import field
|
|
3
|
+
|
|
4
|
+
from dsp_tools.commands.create.constants import KNORA_API_STR
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class ProjectIriLookup:
|
|
9
|
+
project_iri: str
|
|
10
|
+
onto_iris: dict[str, str] = field(default_factory=dict)
|
|
11
|
+
|
|
12
|
+
def add_onto(self, name: str, iri: str) -> None:
|
|
13
|
+
self.onto_iris[name] = iri
|
|
14
|
+
|
|
15
|
+
def get_onto_iri(self, name: str) -> str | None:
|
|
16
|
+
return self.onto_iris.get(name)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclass
|
|
20
|
+
class CreatedIriCollection:
|
|
21
|
+
classes: set[str] = field(default_factory=set)
|
|
22
|
+
properties: set[str] = field(default_factory=set)
|
|
23
|
+
|
|
24
|
+
def __post_init__(self) -> None:
|
|
25
|
+
self.properties.update({f"{KNORA_API_STR}seqnum", f"{KNORA_API_STR}isPartOf"})
|
|
File without changes
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
from typing import cast
|
|
3
|
+
|
|
4
|
+
from dsp_tools.commands.create.models.input_problems import CollectedProblems
|
|
5
|
+
from dsp_tools.commands.create.models.input_problems import CreateProblem
|
|
6
|
+
from dsp_tools.commands.create.models.input_problems import ProblemType
|
|
7
|
+
from dsp_tools.commands.create.models.parsed_ontology import Cardinality
|
|
8
|
+
from dsp_tools.commands.create.models.parsed_ontology import ParsedClass
|
|
9
|
+
from dsp_tools.commands.create.models.parsed_ontology import ParsedClassCardinalities
|
|
10
|
+
from dsp_tools.commands.create.models.parsed_ontology import ParsedOntology
|
|
11
|
+
from dsp_tools.commands.create.models.parsed_ontology import ParsedProperty
|
|
12
|
+
from dsp_tools.commands.create.models.parsed_ontology import ParsedPropertyCardinality
|
|
13
|
+
from dsp_tools.commands.create.parsing.parsing_utils import resolve_to_absolute_iri
|
|
14
|
+
|
|
15
|
+
CARDINALITY_MAPPER = {
|
|
16
|
+
"0-1": Cardinality.C_0_1,
|
|
17
|
+
"1": Cardinality.C_1,
|
|
18
|
+
"0-n": Cardinality.C_0_N,
|
|
19
|
+
"1-n": Cardinality.C_1_N,
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def parse_ontology(ontology_json: dict[str, Any], prefixes: dict[str, str]) -> ParsedOntology | CollectedProblems:
|
|
24
|
+
onto_name = ontology_json["name"]
|
|
25
|
+
current_onto = prefixes[onto_name]
|
|
26
|
+
fails = []
|
|
27
|
+
props, prop_fails = _parse_properties(ontology_json["properties"], current_onto)
|
|
28
|
+
fails.extend(prop_fails)
|
|
29
|
+
classes, cls_fails = _parse_classes(ontology_json["resources"], current_onto)
|
|
30
|
+
fails.extend(cls_fails)
|
|
31
|
+
cards, card_fails = _parse_cardinalities(ontology_json["resources"], current_onto, prefixes)
|
|
32
|
+
fails.extend(card_fails)
|
|
33
|
+
if fails:
|
|
34
|
+
return CollectedProblems(
|
|
35
|
+
f"During the parsing of the ontology '{onto_name}' the following errors occurred", fails
|
|
36
|
+
)
|
|
37
|
+
return ParsedOntology(
|
|
38
|
+
name=onto_name,
|
|
39
|
+
label=ontology_json["label"],
|
|
40
|
+
comment=ontology_json.get("comment"),
|
|
41
|
+
classes=classes,
|
|
42
|
+
properties=props,
|
|
43
|
+
cardinalities=cards,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def _parse_properties(
|
|
48
|
+
properties_list: list[dict[str, Any]], current_onto_prefix: str
|
|
49
|
+
) -> tuple[list[ParsedProperty], list[CreateProblem]]:
|
|
50
|
+
parsed = []
|
|
51
|
+
for prop in properties_list:
|
|
52
|
+
parsed.append(ParsedProperty(f"{current_onto_prefix}{prop['name']}", prop))
|
|
53
|
+
return parsed, []
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _parse_classes(
|
|
57
|
+
classes_list: list[dict[str, Any]], current_onto_prefix: str
|
|
58
|
+
) -> tuple[list[ParsedClass], list[CreateProblem]]:
|
|
59
|
+
parsed = []
|
|
60
|
+
for cls in classes_list:
|
|
61
|
+
parsed.append(ParsedClass(f"{current_onto_prefix}{cls['name']}", cls))
|
|
62
|
+
return parsed, []
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _parse_cardinalities(
|
|
66
|
+
classes_list: list[dict[str, Any]], current_onto_prefix: str, prefixes: dict[str, str]
|
|
67
|
+
) -> tuple[list[ParsedClassCardinalities], list[CreateProblem]]:
|
|
68
|
+
parsed = []
|
|
69
|
+
failures = []
|
|
70
|
+
for c in classes_list:
|
|
71
|
+
if c.get("cardinalities"):
|
|
72
|
+
result = _parse_one_class_cardinality(c, current_onto_prefix, prefixes)
|
|
73
|
+
if isinstance(result, ParsedClassCardinalities):
|
|
74
|
+
parsed.append(result)
|
|
75
|
+
else:
|
|
76
|
+
failures.extend(result)
|
|
77
|
+
return parsed, failures
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _parse_one_class_cardinality(
|
|
81
|
+
cls_json: dict[str, Any], current_onto_prefix: str, prefixes: dict[str, str]
|
|
82
|
+
) -> ParsedClassCardinalities | list[CreateProblem]:
|
|
83
|
+
failures = []
|
|
84
|
+
parsed = []
|
|
85
|
+
for c in cls_json["cardinalities"]:
|
|
86
|
+
result = _parse_one_cardinality(c, current_onto_prefix, prefixes)
|
|
87
|
+
if isinstance(result, ParsedPropertyCardinality):
|
|
88
|
+
parsed.append(result)
|
|
89
|
+
else:
|
|
90
|
+
failures.append(result)
|
|
91
|
+
if failures:
|
|
92
|
+
return failures
|
|
93
|
+
cls_iri = f"{current_onto_prefix}{cls_json['name']}"
|
|
94
|
+
return ParsedClassCardinalities(cls_iri, parsed)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def _parse_one_cardinality(
|
|
98
|
+
card_json: dict[str, str | int], current_onto_prefix: str, prefixes: dict[str, str]
|
|
99
|
+
) -> ParsedPropertyCardinality | CreateProblem:
|
|
100
|
+
prp_name = cast(str, card_json["propname"])
|
|
101
|
+
if not (resolved := resolve_to_absolute_iri(prp_name, current_onto_prefix, prefixes)):
|
|
102
|
+
return CreateProblem(prp_name, ProblemType.PREFIX_COULD_NOT_BE_RESOLVED)
|
|
103
|
+
gui = cast(int | None, card_json.get("gui_order"))
|
|
104
|
+
return ParsedPropertyCardinality(
|
|
105
|
+
propname=resolved,
|
|
106
|
+
cardinality=CARDINALITY_MAPPER[cast(str, card_json["cardinality"])],
|
|
107
|
+
gui_order=gui,
|
|
108
|
+
)
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from loguru import logger
|
|
5
|
+
|
|
6
|
+
from dsp_tools.commands.create.models.input_problems import CollectedProblems
|
|
7
|
+
from dsp_tools.commands.create.models.parsed_ontology import ParsedOntology
|
|
8
|
+
from dsp_tools.commands.create.models.parsed_project import ParsedGroup
|
|
9
|
+
from dsp_tools.commands.create.models.parsed_project import ParsedList
|
|
10
|
+
from dsp_tools.commands.create.models.parsed_project import ParsedPermissions
|
|
11
|
+
from dsp_tools.commands.create.models.parsed_project import ParsedProject
|
|
12
|
+
from dsp_tools.commands.create.models.parsed_project import ParsedProjectMetadata
|
|
13
|
+
from dsp_tools.commands.create.models.parsed_project import ParsedUser
|
|
14
|
+
from dsp_tools.commands.create.parsing.parse_ontology import parse_ontology
|
|
15
|
+
from dsp_tools.commands.create.parsing.parsing_utils import create_prefix_lookup
|
|
16
|
+
from dsp_tools.commands.project.create.project_validate import validate_project
|
|
17
|
+
from dsp_tools.utils.json_parsing import parse_json_input
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def parse_project(
|
|
21
|
+
project_file_as_path_or_parsed: str | Path | dict[str, Any], api_url: str
|
|
22
|
+
) -> ParsedProject | list[CollectedProblems]:
|
|
23
|
+
complete_json = _parse_and_validate(project_file_as_path_or_parsed)
|
|
24
|
+
return _parse_project(complete_json, api_url)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _parse_project(complete_json: dict[str, Any], api_url: str) -> ParsedProject | list[CollectedProblems]:
|
|
28
|
+
prefix_lookup = create_prefix_lookup(complete_json, api_url)
|
|
29
|
+
project_json = complete_json["project"]
|
|
30
|
+
ontologies, failures = _parse_all_ontologies(project_json, prefix_lookup)
|
|
31
|
+
if failures:
|
|
32
|
+
return failures
|
|
33
|
+
return ParsedProject(
|
|
34
|
+
prefixes=prefix_lookup,
|
|
35
|
+
project_metadata=_parse_metadata(project_json),
|
|
36
|
+
permissions=_parse_permissions(project_json),
|
|
37
|
+
groups=_parse_groups(project_json),
|
|
38
|
+
users=_parse_users(project_json),
|
|
39
|
+
lists=_parse_lists(project_json),
|
|
40
|
+
ontologies=ontologies,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _parse_and_validate(project_file_as_path_or_parsed: str | Path | dict[str, Any]) -> dict[str, Any]:
|
|
45
|
+
project_json = parse_json_input(project_file_as_path_or_parsed=project_file_as_path_or_parsed)
|
|
46
|
+
validate_project(project_json)
|
|
47
|
+
print(" JSON project file is syntactically correct and passed validation.")
|
|
48
|
+
logger.info("JSON project file is syntactically correct and passed validation.")
|
|
49
|
+
return project_json
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _parse_metadata(project_json: dict[str, Any]) -> ParsedProjectMetadata:
|
|
53
|
+
return ParsedProjectMetadata(
|
|
54
|
+
shortcode=project_json["shortcode"],
|
|
55
|
+
shortname=project_json["shortname"],
|
|
56
|
+
longname=project_json["longname"],
|
|
57
|
+
descriptions=project_json["descriptions"],
|
|
58
|
+
keywords=project_json["keywords"],
|
|
59
|
+
enabled_licenses=project_json.get("enabled_licenses", []),
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _parse_permissions(project_json: dict[str, Any]) -> ParsedPermissions:
|
|
64
|
+
return ParsedPermissions(
|
|
65
|
+
default_permissions=project_json["default_permissions"],
|
|
66
|
+
default_permissions_overrule=project_json.get("default_permissions_overrule"),
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _parse_groups(project_json: dict[str, Any]) -> list[ParsedGroup]:
|
|
71
|
+
if not (found := project_json.get("groups")):
|
|
72
|
+
return []
|
|
73
|
+
return [ParsedGroup(x) for x in found]
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _parse_users(project_json: dict[str, Any]) -> list[ParsedUser]:
|
|
77
|
+
if not (found := project_json.get("users")):
|
|
78
|
+
return []
|
|
79
|
+
return [ParsedUser(x) for x in found]
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _parse_lists(project_json: dict[str, Any]) -> list[ParsedList]:
|
|
83
|
+
if not (found := project_json.get("lists")):
|
|
84
|
+
return []
|
|
85
|
+
return [ParsedList(x["name"], x) for x in found]
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _parse_all_ontologies(
|
|
89
|
+
project_json: dict[str, Any], prefix_lookup: dict[str, str]
|
|
90
|
+
) -> tuple[list[ParsedOntology], list[CollectedProblems]]:
|
|
91
|
+
ontos = []
|
|
92
|
+
failures = []
|
|
93
|
+
for o in project_json["ontologies"]:
|
|
94
|
+
result = parse_ontology(o, prefix_lookup)
|
|
95
|
+
if isinstance(result, ParsedOntology):
|
|
96
|
+
ontos.append(result)
|
|
97
|
+
else:
|
|
98
|
+
failures.append(result)
|
|
99
|
+
return ontos, failures
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
3
|
+
import regex
|
|
4
|
+
|
|
5
|
+
from dsp_tools.commands.create.constants import KNORA_API_STR
|
|
6
|
+
from dsp_tools.commands.create.constants import UNIVERSAL_PREFIXES
|
|
7
|
+
from dsp_tools.utils.data_formats.uri_util import is_uri
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def resolve_to_absolute_iri(prefixed: str, current_onto: str, prefix_lookup: dict[str, str]) -> str | None:
|
|
11
|
+
if is_uri(prefixed):
|
|
12
|
+
return prefixed
|
|
13
|
+
if prefixed.startswith(":"):
|
|
14
|
+
return f"{current_onto}{prefixed.lstrip(':')}"
|
|
15
|
+
segments = prefixed.split(":", maxsplit=1)
|
|
16
|
+
if len(segments) == 1:
|
|
17
|
+
return f"{KNORA_API_STR}{segments[0]}"
|
|
18
|
+
if not (found := prefix_lookup.get(segments[0])):
|
|
19
|
+
return None
|
|
20
|
+
return f"{found}{segments[1]}"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def create_prefix_lookup(project_json: dict[str, Any], api_url: str) -> dict[str, str]:
|
|
24
|
+
defined_prefixes = project_json.get("prefixes", {})
|
|
25
|
+
defined_prefixes = defined_prefixes | UNIVERSAL_PREFIXES
|
|
26
|
+
defined_prefixes = _correct_external_prefix(defined_prefixes)
|
|
27
|
+
shortcode = project_json["project"]["shortcode"]
|
|
28
|
+
for onto in project_json["project"]["ontologies"]:
|
|
29
|
+
onto_name = onto["name"]
|
|
30
|
+
defined_prefixes[onto_name] = _make_dsp_ontology_prefix(api_url, shortcode, onto_name)
|
|
31
|
+
return defined_prefixes
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _correct_external_prefix(prefixes: dict[str, str]) -> dict[str, str]:
|
|
35
|
+
for prfx, namespace in prefixes.items():
|
|
36
|
+
if regex.search(r"(#|\/)$", namespace):
|
|
37
|
+
continue
|
|
38
|
+
prefixes[prfx] = f"{namespace}/"
|
|
39
|
+
return prefixes
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def _make_dsp_ontology_prefix(api_url: str, shortcode: str, onto_name: str) -> str:
|
|
43
|
+
return f"{api_url}/ontology/{shortcode}/{onto_name}/v2#"
|
|
File without changes
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
from rdflib import OWL
|
|
2
|
+
from rdflib import RDF
|
|
3
|
+
from rdflib import RDFS
|
|
4
|
+
from rdflib import BNode
|
|
5
|
+
from rdflib import Graph
|
|
6
|
+
from rdflib import Literal
|
|
7
|
+
from rdflib import URIRef
|
|
8
|
+
|
|
9
|
+
from dsp_tools.commands.create.constants import SALSAH_GUI
|
|
10
|
+
from dsp_tools.commands.create.create_on_server.mappers import PARSED_CARDINALITY_TO_RDF
|
|
11
|
+
from dsp_tools.commands.create.models.parsed_ontology import ParsedPropertyCardinality
|
|
12
|
+
from dsp_tools.utils.rdflib_constants import KNORA_API
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def make_ontology_base_graph(onto_iri: URIRef, last_modification_date: Literal) -> Graph:
|
|
16
|
+
g = Graph()
|
|
17
|
+
g.add((onto_iri, RDF.type, OWL.Ontology))
|
|
18
|
+
g.add((onto_iri, KNORA_API.lastModificationDate, last_modification_date))
|
|
19
|
+
return g
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def make_cardinality_graph_for_request(
|
|
23
|
+
card: ParsedPropertyCardinality, res_iri: URIRef, onto_iri: URIRef, last_modification_date: Literal
|
|
24
|
+
) -> Graph:
|
|
25
|
+
g = make_ontology_base_graph(onto_iri, last_modification_date)
|
|
26
|
+
g += _make_one_cardinality_graph(card, res_iri)
|
|
27
|
+
return g
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _make_one_cardinality_graph(card: ParsedPropertyCardinality, res_iri: URIRef) -> Graph:
|
|
31
|
+
card_info = PARSED_CARDINALITY_TO_RDF[card.cardinality]
|
|
32
|
+
g = Graph()
|
|
33
|
+
bn_card = BNode()
|
|
34
|
+
g.add((res_iri, RDF.type, OWL.Class))
|
|
35
|
+
g.add((res_iri, RDFS.subClassOf, bn_card))
|
|
36
|
+
g.add((bn_card, RDF.type, OWL.Restriction))
|
|
37
|
+
g.add((bn_card, card_info.owl_property, card_info.cardinality_value))
|
|
38
|
+
g.add((bn_card, OWL.onProperty, URIRef(card.propname)))
|
|
39
|
+
if card.gui_order is not None:
|
|
40
|
+
g.add((bn_card, SALSAH_GUI.guiOrder, Literal(card.gui_order)))
|
|
41
|
+
return g
|
|
@@ -4,6 +4,7 @@ of the project, the creation of groups, users, lists, resource classes, properti
|
|
|
4
4
|
import os
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
from typing import Any
|
|
7
|
+
from typing import cast
|
|
7
8
|
from urllib.parse import quote_plus
|
|
8
9
|
|
|
9
10
|
from dotenv import load_dotenv
|
|
@@ -13,11 +14,14 @@ from dsp_tools.cli.args import ServerCredentials
|
|
|
13
14
|
from dsp_tools.clients.authentication_client_live import AuthenticationClientLive
|
|
14
15
|
from dsp_tools.clients.connection import Connection
|
|
15
16
|
from dsp_tools.clients.connection_live import ConnectionLive
|
|
17
|
+
from dsp_tools.commands.create.communicate_problems import print_problem_collection
|
|
18
|
+
from dsp_tools.commands.create.models.parsed_project import ParsedProject
|
|
19
|
+
from dsp_tools.commands.create.models.server_project_info import ProjectIriLookup
|
|
20
|
+
from dsp_tools.commands.create.parsing.parse_project import parse_project
|
|
16
21
|
from dsp_tools.commands.project.create.parse_project import parse_project_json
|
|
17
22
|
from dsp_tools.commands.project.create.project_create_default_permissions import create_default_permissions
|
|
18
23
|
from dsp_tools.commands.project.create.project_create_lists import create_lists_on_server
|
|
19
24
|
from dsp_tools.commands.project.create.project_create_ontologies import create_ontologies
|
|
20
|
-
from dsp_tools.commands.project.create.project_validate import validate_project
|
|
21
25
|
from dsp_tools.commands.project.legacy_models.context import Context
|
|
22
26
|
from dsp_tools.commands.project.legacy_models.group import Group
|
|
23
27
|
from dsp_tools.commands.project.legacy_models.project import Project
|
|
@@ -34,7 +38,7 @@ from dsp_tools.utils.json_parsing import parse_json_input
|
|
|
34
38
|
load_dotenv()
|
|
35
39
|
|
|
36
40
|
|
|
37
|
-
def create_project( # noqa: PLR0915 (too many statements)
|
|
41
|
+
def create_project( # noqa: PLR0915,PLR0912 (too many statements & branches)
|
|
38
42
|
project_file_as_path_or_parsed: str | Path | dict[str, Any],
|
|
39
43
|
creds: ServerCredentials,
|
|
40
44
|
verbose: bool = False,
|
|
@@ -69,38 +73,41 @@ def create_project( # noqa: PLR0915 (too many statements)
|
|
|
69
73
|
knora_api_prefix = "knora-api:"
|
|
70
74
|
overall_success = True
|
|
71
75
|
|
|
72
|
-
|
|
76
|
+
# includes validation
|
|
77
|
+
parsed_project = parse_project(project_file_as_path_or_parsed, creds.server)
|
|
78
|
+
if not isinstance(parsed_project, ParsedProject):
|
|
79
|
+
for problem in parsed_project:
|
|
80
|
+
print_problem_collection(problem)
|
|
81
|
+
return False
|
|
73
82
|
|
|
83
|
+
# required for the legacy code
|
|
84
|
+
project_json = parse_json_input(project_file_as_path_or_parsed=project_file_as_path_or_parsed)
|
|
74
85
|
context = Context(project_json.get("prefixes", {}))
|
|
75
|
-
|
|
76
|
-
# validate against JSON schema
|
|
77
|
-
validate_project(project_json)
|
|
78
|
-
print(" JSON project file is syntactically correct and passed validation.")
|
|
79
|
-
logger.info("JSON project file is syntactically correct and passed validation.")
|
|
80
|
-
|
|
81
|
-
project = parse_project_json(project_json)
|
|
86
|
+
legacy_project = parse_project_json(project_json)
|
|
82
87
|
|
|
83
88
|
auth = AuthenticationClientLive(creds.server, creds.user, creds.password)
|
|
84
89
|
con = ConnectionLive(creds.server, auth)
|
|
85
90
|
|
|
86
91
|
# create project on DSP server
|
|
87
|
-
info_str = f"Create project '{
|
|
92
|
+
info_str = f"Create project '{legacy_project.metadata.shortname}' ({legacy_project.metadata.shortcode})..."
|
|
88
93
|
print(info_str)
|
|
89
94
|
logger.info(info_str)
|
|
90
95
|
project_remote, success = _create_project_on_server(
|
|
91
|
-
project_definition=
|
|
96
|
+
project_definition=legacy_project.metadata,
|
|
92
97
|
con=con,
|
|
93
98
|
)
|
|
99
|
+
project_iri = cast(str, project_remote.iri)
|
|
100
|
+
project_iri_lookup = ProjectIriLookup(project_iri)
|
|
94
101
|
if not success:
|
|
95
102
|
overall_success = False
|
|
96
103
|
|
|
97
104
|
# create the lists
|
|
98
105
|
names_and_iris_of_list_nodes: dict[str, Any] = {}
|
|
99
|
-
if
|
|
106
|
+
if legacy_project.lists:
|
|
100
107
|
print("Create lists...")
|
|
101
108
|
logger.info("Create lists...")
|
|
102
109
|
names_and_iris_of_list_nodes, success = create_lists_on_server(
|
|
103
|
-
lists_to_create=
|
|
110
|
+
lists_to_create=legacy_project.lists,
|
|
104
111
|
con=con,
|
|
105
112
|
project_remote=project_remote,
|
|
106
113
|
)
|
|
@@ -109,24 +116,24 @@ def create_project( # noqa: PLR0915 (too many statements)
|
|
|
109
116
|
|
|
110
117
|
# create the groups
|
|
111
118
|
current_project_groups: dict[str, Group] = {}
|
|
112
|
-
if
|
|
119
|
+
if legacy_project.groups:
|
|
113
120
|
print("Create groups...")
|
|
114
121
|
logger.info("Create groups...")
|
|
115
122
|
current_project_groups, success = _create_groups(
|
|
116
123
|
con=con,
|
|
117
|
-
groups=
|
|
124
|
+
groups=legacy_project.groups,
|
|
118
125
|
project=project_remote,
|
|
119
126
|
)
|
|
120
127
|
if not success:
|
|
121
128
|
overall_success = False
|
|
122
129
|
|
|
123
130
|
# create or update the users
|
|
124
|
-
if
|
|
131
|
+
if legacy_project.users:
|
|
125
132
|
print("Create users...")
|
|
126
133
|
logger.info("Create users...")
|
|
127
134
|
success = _create_users(
|
|
128
135
|
con=con,
|
|
129
|
-
users_section=
|
|
136
|
+
users_section=legacy_project.users,
|
|
130
137
|
current_project_groups=current_project_groups,
|
|
131
138
|
current_project=project_remote,
|
|
132
139
|
verbose=verbose,
|
|
@@ -140,9 +147,12 @@ def create_project( # noqa: PLR0915 (too many statements)
|
|
|
140
147
|
context=context,
|
|
141
148
|
knora_api_prefix=knora_api_prefix,
|
|
142
149
|
names_and_iris_of_list_nodes=names_and_iris_of_list_nodes,
|
|
143
|
-
ontology_definitions=
|
|
150
|
+
ontology_definitions=legacy_project.ontologies,
|
|
144
151
|
project_remote=project_remote,
|
|
145
152
|
verbose=verbose,
|
|
153
|
+
parsed_ontologies=parsed_project.ontologies,
|
|
154
|
+
project_iri_lookup=project_iri_lookup,
|
|
155
|
+
auth=auth,
|
|
146
156
|
)
|
|
147
157
|
if not success:
|
|
148
158
|
overall_success = False
|
|
@@ -151,9 +161,9 @@ def create_project( # noqa: PLR0915 (too many statements)
|
|
|
151
161
|
perm_client = PermissionsClient(auth, str(project_remote.iri))
|
|
152
162
|
success = create_default_permissions(
|
|
153
163
|
perm_client,
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
164
|
+
legacy_project.metadata.default_permissions,
|
|
165
|
+
legacy_project.metadata.default_permissions_overrule,
|
|
166
|
+
legacy_project.metadata.shortcode,
|
|
157
167
|
)
|
|
158
168
|
if not success:
|
|
159
169
|
overall_success = False
|
|
@@ -161,15 +171,15 @@ def create_project( # noqa: PLR0915 (too many statements)
|
|
|
161
171
|
# final steps
|
|
162
172
|
if overall_success:
|
|
163
173
|
msg = (
|
|
164
|
-
f"Successfully created project '{
|
|
165
|
-
f"({
|
|
174
|
+
f"Successfully created project '{legacy_project.metadata.shortname}' "
|
|
175
|
+
f"({legacy_project.metadata.shortcode}) with all its ontologies. "
|
|
166
176
|
f"There were no problems during the creation process."
|
|
167
177
|
)
|
|
168
178
|
print(f"========================================================\n{msg}")
|
|
169
179
|
logger.info(msg)
|
|
170
180
|
else:
|
|
171
181
|
msg = (
|
|
172
|
-
f"The project '{
|
|
182
|
+
f"The project '{legacy_project.metadata.shortname}' ({legacy_project.metadata.shortcode}) "
|
|
173
183
|
f"with its ontologies could be created, "
|
|
174
184
|
f"but during the creation process, some problems occurred. Please carefully check the console output."
|
|
175
185
|
)
|