Navigation Menu

Skip to content

Commit

Permalink
feat: add support for external ontologies (dev-512) (#170)
Browse files Browse the repository at this point in the history
* update documentation

* add more external ontologies

* code cleanup

* add test data

* clean up code

* update author information

* update bazel version

* rename variables in get method

* make group optional for dsp-tools get

* allow IRIs to not be reduced

* fix merge conflict

* code changes after review

* Update docstring for createDefinitionFileObj
  • Loading branch information
irinaschubert committed Apr 11, 2022
1 parent 6c44688 commit ff36bc1
Show file tree
Hide file tree
Showing 12 changed files with 158 additions and 144 deletions.
18 changes: 9 additions & 9 deletions docs/dsp-tools-create-ontologies.md
Expand Up @@ -891,19 +891,19 @@ Example for a resource definition:

## Referencing Ontologies

For several fields, such as `super` in both `resources` and `properties` or `propname` in `cardinalities`,
it is necessary to reference entities that are defined elsewhere. The following cases are possible.
For several fields, such as `super` in both `resources` and `properties` or `propname` in `cardinalities`
it is necessary to reference entities that are defined elsewhere. The following cases are possible:

- DSP-API internals: These must be written *without* leading colon and should not be a fully qualified IRI.
- DSP API internals: They are referenced as such and do not have a leading colon.
E.g. `Resource`, `DocumentRepresentation` or `hasValue`
- An external ontology: The ontology must be defined in the [prefixes](dsp-tools-create.md#prefixes-object)
This prefix should be used for referencing the ontology.
- An external ontology: The ontology must be defined in the [prefixes](dsp-tools-create.md#prefixes-object) section.
The prefix can then be used for referencing the ontology.
E.g. `foaf:familyName` or `sdo:Organization`
- The current ontology: Within an ontology definition, references can be made by prepending a colon without a prefix.
E.g. `:hasName`
Optionally, an explicit prefix can be used, in this case the ontology must be added to the
[prefixes](dsp-tools-create.md#prefixes-object) and the prefix must be identical to the ontology's `name`.
E.g. `:hasName`
Optionally, an explicit prefix can be used. In this case the ontology must be added to the
[prefixes](dsp-tools-create.md#prefixes-object) section and the prefix must be identical to the ontology's `name`.
- A different ontology defined in the same file: Within one data model file, multiple ontologies can be defined.
These will be created in the exact order they appear in the `ontologies` array. Once an ontology has been created,
it can be referenced by the following ontologies via its name: `first-onto:hasName`. It is not necessary to add
it can be referenced by the following ontologies by its name, e.g. `first-onto:hasName`. It is not necessary to add
`first-onto` to the prefixes.
13 changes: 7 additions & 6 deletions docs/dsp-tools-create.md
Expand Up @@ -52,10 +52,10 @@ A complete data model definition for DSP looks like this:

`"prefixes": { "prefix": "<iri>", ...}`

The `prefixes` object contains the prefixes of external ontologies that are used in the current project. All prefixes
are composed of the actual prefix and an IRI. The prefix is used as an abbreviation so one does not have to write the
full qualified IRI each time it is used. So, instead of writing a property called "familyname" as
`http://xmlns.com/foaf/0.1/familyName` one can simply use `foaf:familyName`.
The `prefixes` object contains the prefixes of external ontologies that are used in the current file. All prefixes
are composed of the prefix and a URI. The prefix is used as namespace so one does not have to write the
fully qualified name of the referenced object each time it is used. Instead of writing a property called "familyName"
as `http://xmlns.com/foaf/0.1/familyName` one can simply write `foaf:familyName`.

```json
{
Expand All @@ -66,8 +66,9 @@ full qualified IRI each time it is used. So, instead of writing a property calle
}
```

It is not necessary to define prefixes for the ontologies that are defined in this file. Ontologies in the same
file can refer to each other via their name. See also [here](./dsp-tools-create-ontologies.md#referencing-ontologies).
It is not necessary to define prefixes for the ontologies that are defined in the same file. Ontologies in the same
file can be referenced by their name. See [this section](./dsp-tools-create-ontologies.md#referencing-ontologies) for
more information about referencing ontologies.

### "$schema" object

Expand Down
25 changes: 12 additions & 13 deletions knora/dsplib/models/connection.py
@@ -1,6 +1,6 @@
import json
import re
from typing import Optional, Union
from typing import Optional, Union, Any

import requests
from pystrict import strict
Expand Down Expand Up @@ -159,7 +159,7 @@ def post(self, path: str, jsondata: Optional[str] = None):
result = req.json()
return result

def get(self, path: str, headers: Optional[dict[str, str]] = None):
def get(self, path: str, headers: Optional[dict[str, str]] = None) -> dict[str, Any]:
"""
Get data from a server using a HTTP GET request
:param path: Path of RESTful route
Expand All @@ -169,22 +169,21 @@ def get(self, path: str, headers: Optional[dict[str, str]] = None):

if path[0] != '/':
path = '/' + path
if self._token is None:
if headers is None:
req = requests.get(self._server + path)
if not self._token:
if not headers:
response = requests.get(self._server + path)
else:
req = requests.get(self._server + path, headers)
response = requests.get(self._server + path, headers)
else:
if headers is None:
req = requests.get(self._server + path,
headers={'Authorization': 'Bearer ' + self._token})
if not headers:
response = requests.get(self._server + path, headers={'Authorization': 'Bearer ' + self._token})
else:
headers['Authorization'] = 'Bearer ' + self._token
req = requests.get(self._server + path, headers)
response = requests.get(self._server + path, headers)

self.on_api_error(req)
result = req.json()
return result
self.on_api_error(response)
json_response = response.json()
return json_response

def put(self, path: str, jsondata: Optional[str] = None, content_type: str = 'application/json'):
"""
Expand Down
24 changes: 11 additions & 13 deletions knora/dsplib/models/group.py
Expand Up @@ -160,8 +160,8 @@ def has_changed(self) -> bool:

@classmethod
def fromJsonObj(cls, con: Connection, json_obj: Any):
id = json_obj.get('id')
if id is None:
group_id = json_obj.get('id')
if group_id is None:
raise BaseError('Group "id" is missing')
name = json_obj.get('name')
if name is None:
Expand All @@ -181,7 +181,7 @@ def fromJsonObj(cls, con: Connection, json_obj: Any):
raise BaseError("Status is missing")
return cls(con=con,
name=name,
id=id,
id=group_id,
descriptions=descriptions,
project=project,
selfjoin=selfjoin,
Expand Down Expand Up @@ -249,16 +249,14 @@ def getAllGroups(con: Connection) -> Optional[list[Group]]:
return None

@staticmethod
def getAllGroupsForProject(con: Connection, proj_shortcode: str) -> list[Group]:
result = con.get(Group.ROUTE)
if 'groups' not in result:
raise BaseError("Request got no groups!")
all_groups = result["groups"]
project_groups = []
for group in all_groups:
if group["project"]["id"] == "http://rdfh.ch/projects/" + proj_shortcode:
project_groups.append(group)
return list(map(lambda a: Group.fromJsonObj(con, a), project_groups))
def getAllGroupsForProject(con: Connection, proj_shortcode: str) -> Optional[list[Group]]:
all_groups: Optional[list[Group]] = Group.getAllGroups(con)
if all_groups:
project_groups = []
for group in all_groups:
if group.project == "http://rdfh.ch/projects/" + proj_shortcode:
project_groups.append(group)
return project_groups

def createDefinitionFileObj(self):
group = {
Expand Down

0 comments on commit ff36bc1

Please sign in to comment.