personal_knowledge_library 3.0.0__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 personal_knowledge_library might be problematic. Click here for more details.
- knowledge/__init__.py +91 -0
- knowledge/base/__init__.py +22 -0
- knowledge/base/access.py +167 -0
- knowledge/base/entity.py +267 -0
- knowledge/base/language.py +27 -0
- knowledge/base/ontology.py +2734 -0
- knowledge/base/search.py +473 -0
- knowledge/base/tenant.py +192 -0
- knowledge/nel/__init__.py +11 -0
- knowledge/nel/base.py +495 -0
- knowledge/nel/engine.py +123 -0
- knowledge/ontomapping/__init__.py +667 -0
- knowledge/ontomapping/manager.py +320 -0
- knowledge/public/__init__.py +27 -0
- knowledge/public/cache.py +115 -0
- knowledge/public/helper.py +373 -0
- knowledge/public/relations.py +128 -0
- knowledge/public/wikidata.py +1324 -0
- knowledge/services/__init__.py +128 -0
- knowledge/services/asyncio/__init__.py +7 -0
- knowledge/services/asyncio/base.py +458 -0
- knowledge/services/asyncio/graph.py +1420 -0
- knowledge/services/asyncio/group.py +450 -0
- knowledge/services/asyncio/search.py +439 -0
- knowledge/services/asyncio/users.py +270 -0
- knowledge/services/base.py +533 -0
- knowledge/services/graph.py +1897 -0
- knowledge/services/group.py +819 -0
- knowledge/services/helper.py +142 -0
- knowledge/services/ontology.py +1234 -0
- knowledge/services/search.py +488 -0
- knowledge/services/session.py +444 -0
- knowledge/services/tenant.py +281 -0
- knowledge/services/users.py +445 -0
- knowledge/utils/__init__.py +10 -0
- knowledge/utils/graph.py +417 -0
- knowledge/utils/wikidata.py +197 -0
- knowledge/utils/wikipedia.py +175 -0
- personal_knowledge_library-3.0.0.dist-info/LICENSE +201 -0
- personal_knowledge_library-3.0.0.dist-info/METADATA +1163 -0
- personal_knowledge_library-3.0.0.dist-info/RECORD +42 -0
- personal_knowledge_library-3.0.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,1897 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright © 2021-present Wacom. All rights reserved.
|
|
3
|
+
import enum
|
|
4
|
+
import gzip
|
|
5
|
+
import json
|
|
6
|
+
import os
|
|
7
|
+
import urllib
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any, Optional, List, Dict, Tuple, Literal
|
|
10
|
+
from urllib.parse import urlparse
|
|
11
|
+
|
|
12
|
+
import requests
|
|
13
|
+
from requests import Response
|
|
14
|
+
from requests.adapters import HTTPAdapter
|
|
15
|
+
from urllib3 import Retry
|
|
16
|
+
|
|
17
|
+
from knowledge.base.entity import (
|
|
18
|
+
DATA_PROPERTIES_TAG,
|
|
19
|
+
TYPE_TAG,
|
|
20
|
+
LABELS_TAG,
|
|
21
|
+
IS_MAIN_TAG,
|
|
22
|
+
RELATIONS_TAG,
|
|
23
|
+
LOCALE_TAG,
|
|
24
|
+
EntityStatus,
|
|
25
|
+
Label,
|
|
26
|
+
URIS_TAG,
|
|
27
|
+
FORCE_TAG,
|
|
28
|
+
URI_TAG,
|
|
29
|
+
)
|
|
30
|
+
from knowledge.base.language import LocaleCode
|
|
31
|
+
from knowledge.base.ontology import (
|
|
32
|
+
DataProperty,
|
|
33
|
+
OntologyPropertyReference,
|
|
34
|
+
ThingObject,
|
|
35
|
+
OntologyClassReference,
|
|
36
|
+
ObjectProperty,
|
|
37
|
+
EN_US,
|
|
38
|
+
)
|
|
39
|
+
from knowledge.services import (
|
|
40
|
+
AUTHORIZATION_HEADER_FLAG,
|
|
41
|
+
APPLICATION_JSON_HEADER,
|
|
42
|
+
RELATION_TAG,
|
|
43
|
+
TARGET,
|
|
44
|
+
ACTIVATION_TAG,
|
|
45
|
+
PREDICATE,
|
|
46
|
+
OBJECT,
|
|
47
|
+
SUBJECT,
|
|
48
|
+
LIMIT_PARAMETER,
|
|
49
|
+
ESTIMATE_COUNT,
|
|
50
|
+
VISIBILITY_TAG,
|
|
51
|
+
NEXT_PAGE_ID_TAG,
|
|
52
|
+
LISTING,
|
|
53
|
+
TOTAL_COUNT,
|
|
54
|
+
SEARCH_TERM,
|
|
55
|
+
LANGUAGE_PARAMETER,
|
|
56
|
+
TYPES_PARAMETER,
|
|
57
|
+
LIMIT,
|
|
58
|
+
VALUE,
|
|
59
|
+
LITERAL_PARAMETER,
|
|
60
|
+
SEARCH_PATTERN_PARAMETER,
|
|
61
|
+
SUBJECT_URI,
|
|
62
|
+
RELATION_URI,
|
|
63
|
+
OBJECT_URI,
|
|
64
|
+
DEFAULT_TIMEOUT,
|
|
65
|
+
IS_OWNER_PARAM,
|
|
66
|
+
PRUNE_PARAM,
|
|
67
|
+
STATUS_FORCE_LIST,
|
|
68
|
+
DEFAULT_MAX_RETRIES,
|
|
69
|
+
DEFAULT_BACKOFF_FACTOR,
|
|
70
|
+
ENTITIES_TAG,
|
|
71
|
+
NEL_PARAM,
|
|
72
|
+
)
|
|
73
|
+
from knowledge.services.base import (
|
|
74
|
+
WacomServiceAPIClient,
|
|
75
|
+
WacomServiceException,
|
|
76
|
+
USER_AGENT_HEADER_FLAG,
|
|
77
|
+
CONTENT_TYPE_HEADER_FLAG,
|
|
78
|
+
handle_error,
|
|
79
|
+
)
|
|
80
|
+
from knowledge.services.helper import split_updates, entity_payload
|
|
81
|
+
from knowledge.services.users import UserRole
|
|
82
|
+
|
|
83
|
+
MIME_TYPE: Dict[str, str] = {".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".png": "image/png"}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
# ------------------------------- Enum ---------------------------------------------------------------------------------
|
|
87
|
+
class SearchPattern(enum.Enum):
|
|
88
|
+
"""
|
|
89
|
+
SearchPattern
|
|
90
|
+
-------------
|
|
91
|
+
Different search pattern for literal search.
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
REGEX = "regex"
|
|
95
|
+
"""Regular expression search pattern."""
|
|
96
|
+
GT = "gt"
|
|
97
|
+
"""Greater than search pattern."""
|
|
98
|
+
GTE = "gte"
|
|
99
|
+
"""Greater than or equal search pattern."""
|
|
100
|
+
LT = "lt"
|
|
101
|
+
"""Less than search pattern."""
|
|
102
|
+
LTE = "lte"
|
|
103
|
+
"""Less than or equal search pattern."""
|
|
104
|
+
EQ = "eq"
|
|
105
|
+
"""Equal search pattern."""
|
|
106
|
+
RANGE = "range"
|
|
107
|
+
"""Range search pattern."""
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class Visibility(enum.Enum):
|
|
111
|
+
"""
|
|
112
|
+
Visibility
|
|
113
|
+
----------
|
|
114
|
+
Visibility of an entity.
|
|
115
|
+
The visibility of an entity determines who can see the entity.
|
|
116
|
+
"""
|
|
117
|
+
|
|
118
|
+
PRIVATE = "Private"
|
|
119
|
+
"""Only the owner of the entity can see the entity."""
|
|
120
|
+
PUBLIC = "Public"
|
|
121
|
+
"""Everyone in the tenant can see the entity."""
|
|
122
|
+
SHARED = "Shared"
|
|
123
|
+
"""Everyone who joined the group can see the entity."""
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
# -------------------------------------------- Service API Client ------------------------------------------------------
|
|
127
|
+
class WacomKnowledgeService(WacomServiceAPIClient):
|
|
128
|
+
"""
|
|
129
|
+
WacomKnowledgeService
|
|
130
|
+
---------------------
|
|
131
|
+
Client for the Semantic Ink Private knowledge system.
|
|
132
|
+
|
|
133
|
+
Operations for entities:
|
|
134
|
+
- Creation of entities
|
|
135
|
+
- Update of entities
|
|
136
|
+
- Deletion of entities
|
|
137
|
+
- Listing of entities
|
|
138
|
+
|
|
139
|
+
Parameters
|
|
140
|
+
----------
|
|
141
|
+
application_name: str
|
|
142
|
+
Name of the application using the service
|
|
143
|
+
service_url: str
|
|
144
|
+
URL of the service
|
|
145
|
+
service_endpoint: str
|
|
146
|
+
Base endpoint
|
|
147
|
+
"""
|
|
148
|
+
|
|
149
|
+
USER_ENDPOINT: str = "user"
|
|
150
|
+
ENTITY_ENDPOINT: str = "entity"
|
|
151
|
+
ENTITY_BULK_ENDPOINT: str = "entity/bulk"
|
|
152
|
+
ENTITY_IMAGE_ENDPOINT: str = "entity/image/"
|
|
153
|
+
ACTIVATIONS_ENDPOINT: str = "entity/activations"
|
|
154
|
+
LISTING_ENDPOINT: str = "entity/types"
|
|
155
|
+
RELATION_ENDPOINT: str = "entity/{}/relation"
|
|
156
|
+
RELATIONS_ENDPOINT: str = "entity/{}/relations"
|
|
157
|
+
SEARCH_LABELS_ENDPOINT: str = "semantic-search/labels"
|
|
158
|
+
SEARCH_TYPES_ENDPOINT: str = "semantic-search/types"
|
|
159
|
+
SEARCH_LITERALS_ENDPOINT: str = "semantic-search/literal"
|
|
160
|
+
SEARCH_DESCRIPTION_ENDPOINT: str = "semantic-search/description"
|
|
161
|
+
SEARCH_RELATION_ENDPOINT: str = "semantic-search/relation"
|
|
162
|
+
ONTOLOGY_UPDATE_ENDPOINT: str = "ontology-update"
|
|
163
|
+
IMPORT_ENTITIES_ENDPOINT: str = "import"
|
|
164
|
+
REBUILD_VECTOR_SEARCH_INDEX: str = "vector-search/rebuild"
|
|
165
|
+
REBUILD_NEL_INDEX: str = "nel/rebuild"
|
|
166
|
+
|
|
167
|
+
def __init__(
|
|
168
|
+
self,
|
|
169
|
+
application_name: str = "Knowledge Client",
|
|
170
|
+
service_url: str = WacomServiceAPIClient.SERVICE_URL,
|
|
171
|
+
service_endpoint: str = "graph/v1",
|
|
172
|
+
):
|
|
173
|
+
super().__init__(application_name, service_url, service_endpoint)
|
|
174
|
+
|
|
175
|
+
def entity(
|
|
176
|
+
self,
|
|
177
|
+
uri: str,
|
|
178
|
+
auth_key: Optional[str] = None,
|
|
179
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
180
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
181
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
182
|
+
) -> ThingObject:
|
|
183
|
+
"""
|
|
184
|
+
Retrieve entity information from personal knowledge, using the URI as identifier.
|
|
185
|
+
|
|
186
|
+
**Remark:** Object properties (relations) must be requested separately.
|
|
187
|
+
|
|
188
|
+
Parameters
|
|
189
|
+
----------
|
|
190
|
+
uri: str
|
|
191
|
+
URI of entity
|
|
192
|
+
auth_key: Optional[str]
|
|
193
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
194
|
+
timeout: int
|
|
195
|
+
Timeout for the request (default: 60 seconds)
|
|
196
|
+
max_retries: int
|
|
197
|
+
Maximum number of retries (default: 3)
|
|
198
|
+
backoff_factor: float
|
|
199
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
200
|
+
second try without a delay) (default: 0.1)
|
|
201
|
+
|
|
202
|
+
Returns
|
|
203
|
+
-------
|
|
204
|
+
thing: ThingObject
|
|
205
|
+
Entity with is type URI, description, an image/icon, and tags (labels).
|
|
206
|
+
|
|
207
|
+
Raises
|
|
208
|
+
------
|
|
209
|
+
WacomServiceException
|
|
210
|
+
If the graph service returns an error code or the entity is not found in the knowledge graph
|
|
211
|
+
"""
|
|
212
|
+
if auth_key is None:
|
|
213
|
+
auth_key, _ = self.handle_token()
|
|
214
|
+
url: str = f"{self.service_base_url}{WacomKnowledgeService.ENTITY_ENDPOINT}/{uri}"
|
|
215
|
+
headers: Dict[str, str] = {
|
|
216
|
+
USER_AGENT_HEADER_FLAG: self.user_agent,
|
|
217
|
+
AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}",
|
|
218
|
+
}
|
|
219
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
220
|
+
with requests.Session() as session:
|
|
221
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
222
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
223
|
+
response: Response = session.get(url, headers=headers, timeout=timeout, verify=self.verify_calls)
|
|
224
|
+
if response.ok:
|
|
225
|
+
e: Dict[str, Any] = response.json()
|
|
226
|
+
pref_label: List[Label] = []
|
|
227
|
+
aliases: List[Label] = []
|
|
228
|
+
# Extract labels and alias
|
|
229
|
+
for label in e[LABELS_TAG]:
|
|
230
|
+
if label[IS_MAIN_TAG]: # Labels
|
|
231
|
+
pref_label.append(Label.create_from_dict(label))
|
|
232
|
+
else: # Alias
|
|
233
|
+
aliases.append(Label.create_from_dict(label))
|
|
234
|
+
thing: ThingObject = ThingObject.from_dict(e)
|
|
235
|
+
return thing
|
|
236
|
+
raise handle_error(f"Retrieving of entity content failed. URI:={uri}.", response)
|
|
237
|
+
|
|
238
|
+
def delete_entities(
|
|
239
|
+
self,
|
|
240
|
+
uris: List[str],
|
|
241
|
+
force: bool = False,
|
|
242
|
+
auth_key: Optional[str] = None,
|
|
243
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
244
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
245
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
246
|
+
):
|
|
247
|
+
"""
|
|
248
|
+
Delete a list of entities.
|
|
249
|
+
|
|
250
|
+
Parameters
|
|
251
|
+
----------
|
|
252
|
+
uris: List[str]
|
|
253
|
+
List of URI of entities. **Remark:** More than 100 entities are not possible in one request
|
|
254
|
+
force: bool
|
|
255
|
+
Force deletion process
|
|
256
|
+
auth_key: Optional[str] [default:= None]
|
|
257
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
258
|
+
timeout: int
|
|
259
|
+
Timeout for the request (default: 60 seconds)
|
|
260
|
+
max_retries: int
|
|
261
|
+
Maximum number of retries
|
|
262
|
+
backoff_factor: float
|
|
263
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
264
|
+
second try without a delay)
|
|
265
|
+
|
|
266
|
+
Raises
|
|
267
|
+
------
|
|
268
|
+
WacomServiceException
|
|
269
|
+
If the graph service returns an error code
|
|
270
|
+
ValueError
|
|
271
|
+
If more than 100 entities are given
|
|
272
|
+
"""
|
|
273
|
+
if len(uris) > 100:
|
|
274
|
+
raise ValueError("Please delete less than 100 entities.")
|
|
275
|
+
if auth_key is None:
|
|
276
|
+
auth_key, _ = self.handle_token()
|
|
277
|
+
url: str = f"{self.service_base_url}{WacomKnowledgeService.ENTITY_ENDPOINT}"
|
|
278
|
+
headers: Dict[str, str] = {
|
|
279
|
+
USER_AGENT_HEADER_FLAG: self.user_agent,
|
|
280
|
+
AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}",
|
|
281
|
+
}
|
|
282
|
+
params: Dict[str, Any] = {URIS_TAG: uris, FORCE_TAG: force}
|
|
283
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
284
|
+
with requests.Session() as session:
|
|
285
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
286
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
287
|
+
response: Response = session.delete(
|
|
288
|
+
url, headers=headers, params=params, timeout=timeout, verify=self.verify_calls
|
|
289
|
+
)
|
|
290
|
+
if not response.ok:
|
|
291
|
+
raise handle_error("Deletion of entities failed.", response)
|
|
292
|
+
|
|
293
|
+
def delete_entity(
|
|
294
|
+
self,
|
|
295
|
+
uri: str,
|
|
296
|
+
force: bool = False,
|
|
297
|
+
auth_key: Optional[str] = None,
|
|
298
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
299
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
300
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
301
|
+
):
|
|
302
|
+
"""
|
|
303
|
+
Deletes an entity.
|
|
304
|
+
|
|
305
|
+
Parameters
|
|
306
|
+
----------
|
|
307
|
+
uri: str
|
|
308
|
+
URI of entity
|
|
309
|
+
force: bool
|
|
310
|
+
Force deletion process
|
|
311
|
+
auth_key: Optional[str]
|
|
312
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
313
|
+
timeout: int
|
|
314
|
+
Timeout for the request (default: 60 seconds)
|
|
315
|
+
max_retries: int
|
|
316
|
+
Maximum number of retries
|
|
317
|
+
backoff_factor: float
|
|
318
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
319
|
+
second try without a delay)
|
|
320
|
+
|
|
321
|
+
Raises
|
|
322
|
+
------
|
|
323
|
+
WacomServiceException
|
|
324
|
+
If the graph service returns an error code
|
|
325
|
+
"""
|
|
326
|
+
if auth_key is None:
|
|
327
|
+
auth_key, _ = self.handle_token()
|
|
328
|
+
url: str = f"{self.service_base_url}{WacomKnowledgeService.ENTITY_ENDPOINT}/{uri}"
|
|
329
|
+
headers: Dict[str, str] = {
|
|
330
|
+
USER_AGENT_HEADER_FLAG: self.user_agent,
|
|
331
|
+
AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}",
|
|
332
|
+
}
|
|
333
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
334
|
+
with requests.Session() as session:
|
|
335
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
336
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
337
|
+
response: Response = session.delete(
|
|
338
|
+
url, headers=headers, params={FORCE_TAG: force}, timeout=timeout, verify=self.verify_calls
|
|
339
|
+
)
|
|
340
|
+
if not response.ok:
|
|
341
|
+
raise handle_error(f"Deletion of entity (URI:={uri}) failed.", response)
|
|
342
|
+
|
|
343
|
+
def exists(
|
|
344
|
+
self,
|
|
345
|
+
uri: str,
|
|
346
|
+
auth_key: Optional[str] = None,
|
|
347
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
348
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
349
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
350
|
+
) -> bool:
|
|
351
|
+
"""
|
|
352
|
+
Check if entity exists in knowledge graph.
|
|
353
|
+
|
|
354
|
+
Parameters
|
|
355
|
+
----------
|
|
356
|
+
uri: str -
|
|
357
|
+
URI for entity
|
|
358
|
+
auth_key: Optional[str]
|
|
359
|
+
Auth key from user
|
|
360
|
+
timeout: int
|
|
361
|
+
Timeout for the request (default: 60 seconds)
|
|
362
|
+
max_retries: int
|
|
363
|
+
Maximum number of retries (default: 3)
|
|
364
|
+
backoff_factor: float
|
|
365
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
366
|
+
second try without a delay) (default: 0.1)
|
|
367
|
+
|
|
368
|
+
Returns
|
|
369
|
+
-------
|
|
370
|
+
flag: bool
|
|
371
|
+
Flag if entity does exist
|
|
372
|
+
"""
|
|
373
|
+
try:
|
|
374
|
+
obj: ThingObject = self.entity(
|
|
375
|
+
uri, auth_key=auth_key, timeout=timeout, max_retries=max_retries, backoff_factor=backoff_factor
|
|
376
|
+
)
|
|
377
|
+
return obj is not None
|
|
378
|
+
except WacomServiceException:
|
|
379
|
+
return False
|
|
380
|
+
|
|
381
|
+
@staticmethod
|
|
382
|
+
def __entity__(entity: ThingObject):
|
|
383
|
+
return entity_payload(entity)
|
|
384
|
+
|
|
385
|
+
def create_entity_bulk(
|
|
386
|
+
self,
|
|
387
|
+
entities: List[ThingObject],
|
|
388
|
+
batch_size: int = 10,
|
|
389
|
+
ignore_images: bool = False,
|
|
390
|
+
auth_key: Optional[str] = None,
|
|
391
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
392
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
393
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
394
|
+
) -> List[ThingObject]:
|
|
395
|
+
"""
|
|
396
|
+
Creates entity in graph.
|
|
397
|
+
|
|
398
|
+
Parameters
|
|
399
|
+
----------
|
|
400
|
+
entities: List[ThingObject]
|
|
401
|
+
Entities
|
|
402
|
+
batch_size: int
|
|
403
|
+
Batch size
|
|
404
|
+
ignore_images: bool
|
|
405
|
+
Ignore images
|
|
406
|
+
auth_key: Optional[str]
|
|
407
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
408
|
+
timeout: int
|
|
409
|
+
Timeout for the request (default: 60 seconds).
|
|
410
|
+
max_retries: int
|
|
411
|
+
Maximum number of retries
|
|
412
|
+
backoff_factor: float
|
|
413
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
414
|
+
second try without a delay)
|
|
415
|
+
|
|
416
|
+
Returns
|
|
417
|
+
-------
|
|
418
|
+
things: List[ThingObject]
|
|
419
|
+
List of entities with URI
|
|
420
|
+
|
|
421
|
+
Raises
|
|
422
|
+
------
|
|
423
|
+
WacomServiceException
|
|
424
|
+
If the graph service returns an error code
|
|
425
|
+
"""
|
|
426
|
+
url: str = f"{self.service_base_url}{WacomKnowledgeService.ENTITY_BULK_ENDPOINT}"
|
|
427
|
+
# Header info
|
|
428
|
+
headers: Dict[str, str] = {
|
|
429
|
+
USER_AGENT_HEADER_FLAG: self.user_agent,
|
|
430
|
+
CONTENT_TYPE_HEADER_FLAG: APPLICATION_JSON_HEADER,
|
|
431
|
+
AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}",
|
|
432
|
+
}
|
|
433
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
434
|
+
with requests.Session() as session:
|
|
435
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
436
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
437
|
+
payload: List[Dict[str, Any]] = [WacomKnowledgeService.__entity__(e) for e in entities]
|
|
438
|
+
for bulk_idx in range(0, len(entities), batch_size):
|
|
439
|
+
bulk = payload[bulk_idx : bulk_idx + batch_size]
|
|
440
|
+
response: Response = session.post(
|
|
441
|
+
url, json=bulk, headers=headers, timeout=timeout, verify=self.verify_calls
|
|
442
|
+
)
|
|
443
|
+
if response.ok:
|
|
444
|
+
response_dict: Dict[str, Any] = response.json()
|
|
445
|
+
|
|
446
|
+
for idx, uri in enumerate(response_dict[URIS_TAG]):
|
|
447
|
+
if (
|
|
448
|
+
entities[bulk_idx + idx].image is not None
|
|
449
|
+
and entities[bulk_idx + idx].image != ""
|
|
450
|
+
and not ignore_images
|
|
451
|
+
):
|
|
452
|
+
self.set_entity_image_url(uri, entities[bulk_idx + idx].image, auth_key=auth_key)
|
|
453
|
+
entities[bulk_idx + idx].uri = response_dict[URIS_TAG][idx]
|
|
454
|
+
else:
|
|
455
|
+
raise handle_error("Pushing entity failed.", response)
|
|
456
|
+
return entities
|
|
457
|
+
|
|
458
|
+
def create_entity(
|
|
459
|
+
self,
|
|
460
|
+
entity: ThingObject,
|
|
461
|
+
ignore_image: bool = False,
|
|
462
|
+
auth_key: Optional[str] = None,
|
|
463
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
464
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
465
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
466
|
+
) -> str:
|
|
467
|
+
"""
|
|
468
|
+
Creates entity in graph.
|
|
469
|
+
|
|
470
|
+
Parameters
|
|
471
|
+
----------
|
|
472
|
+
entity: ThingObject
|
|
473
|
+
Entity object that needs to be created
|
|
474
|
+
ignore_image: bool [default:= False]
|
|
475
|
+
Ignore image.
|
|
476
|
+
auth_key: Optional[str]
|
|
477
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
478
|
+
max_retries: int [default:= 3]
|
|
479
|
+
Maximum number of retries
|
|
480
|
+
backoff_factor: float [default:= 0.1]
|
|
481
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
482
|
+
second try without a delay)
|
|
483
|
+
timeout: int [default:= 5]
|
|
484
|
+
Timeout for the request
|
|
485
|
+
Returns
|
|
486
|
+
-------
|
|
487
|
+
uri: str
|
|
488
|
+
URI of entity
|
|
489
|
+
|
|
490
|
+
Raises
|
|
491
|
+
------
|
|
492
|
+
WacomServiceException
|
|
493
|
+
If the graph service returns an error code
|
|
494
|
+
"""
|
|
495
|
+
if auth_key is None:
|
|
496
|
+
auth_key, _ = self.handle_token()
|
|
497
|
+
url: str = f"{self.service_base_url}{WacomKnowledgeService.ENTITY_ENDPOINT}"
|
|
498
|
+
# Header info
|
|
499
|
+
headers: Dict[str, str] = {
|
|
500
|
+
USER_AGENT_HEADER_FLAG: self.user_agent,
|
|
501
|
+
CONTENT_TYPE_HEADER_FLAG: APPLICATION_JSON_HEADER,
|
|
502
|
+
AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}",
|
|
503
|
+
}
|
|
504
|
+
payload: Dict[str, Any] = WacomKnowledgeService.__entity__(entity)
|
|
505
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
506
|
+
with requests.Session() as session:
|
|
507
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
508
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
509
|
+
response: Response = session.post(
|
|
510
|
+
url, json=payload, headers=headers, verify=self.verify_calls, timeout=timeout
|
|
511
|
+
)
|
|
512
|
+
|
|
513
|
+
if response.ok and not ignore_image:
|
|
514
|
+
uri: str = response.json()[URI_TAG]
|
|
515
|
+
# Set image
|
|
516
|
+
try:
|
|
517
|
+
if entity.image is not None and entity.image.startswith("file:"):
|
|
518
|
+
p = urlparse(entity.image)
|
|
519
|
+
self.set_entity_image_local(uri, Path(p.path), auth_key=auth_key)
|
|
520
|
+
elif entity.image is not None and entity.image != "":
|
|
521
|
+
self.set_entity_image_url(uri, entity.image, auth_key=auth_key)
|
|
522
|
+
except WacomServiceException as _:
|
|
523
|
+
pass
|
|
524
|
+
if response.ok:
|
|
525
|
+
uri: str = response.json()[URI_TAG]
|
|
526
|
+
return uri
|
|
527
|
+
raise handle_error("Pushing entity failed.", response)
|
|
528
|
+
|
|
529
|
+
def update_entity(
|
|
530
|
+
self,
|
|
531
|
+
entity: ThingObject,
|
|
532
|
+
auth_key: Optional[str] = None,
|
|
533
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
534
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
535
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
536
|
+
):
|
|
537
|
+
"""
|
|
538
|
+
Updates entity in graph.
|
|
539
|
+
|
|
540
|
+
Parameters
|
|
541
|
+
----------
|
|
542
|
+
entity: ThingObject
|
|
543
|
+
entity object
|
|
544
|
+
auth_key: Optional[str]
|
|
545
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
546
|
+
timeout: int
|
|
547
|
+
Timeout for the request (default: 60 seconds)
|
|
548
|
+
max_retries: int
|
|
549
|
+
Maximum number of retries
|
|
550
|
+
backoff_factor: float
|
|
551
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
552
|
+
second try without a delay)
|
|
553
|
+
|
|
554
|
+
Raises
|
|
555
|
+
------
|
|
556
|
+
WacomServiceException
|
|
557
|
+
If the graph service returns an error code
|
|
558
|
+
"""
|
|
559
|
+
if auth_key is None:
|
|
560
|
+
auth_key, _ = self.handle_token()
|
|
561
|
+
uri: str = entity.uri
|
|
562
|
+
url: str = f"{self.service_base_url}{WacomKnowledgeService.ENTITY_ENDPOINT}/{uri}"
|
|
563
|
+
# Header info
|
|
564
|
+
headers: dict = {
|
|
565
|
+
USER_AGENT_HEADER_FLAG: self.user_agent,
|
|
566
|
+
CONTENT_TYPE_HEADER_FLAG: APPLICATION_JSON_HEADER,
|
|
567
|
+
AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}",
|
|
568
|
+
}
|
|
569
|
+
payload: Dict[str, Any] = WacomKnowledgeService.__entity__(entity)
|
|
570
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
571
|
+
with requests.Session() as session:
|
|
572
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
573
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
574
|
+
response: Response = session.patch(
|
|
575
|
+
url, json=payload, headers=headers, timeout=timeout, verify=self.verify_calls
|
|
576
|
+
)
|
|
577
|
+
if not response.ok:
|
|
578
|
+
raise handle_error("Updating entity failed.", response)
|
|
579
|
+
|
|
580
|
+
def relations(
|
|
581
|
+
self,
|
|
582
|
+
uri: str,
|
|
583
|
+
auth_key: Optional[str] = None,
|
|
584
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
585
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
586
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
587
|
+
) -> Dict[OntologyPropertyReference, ObjectProperty]:
|
|
588
|
+
"""
|
|
589
|
+
Retrieve the relations (object properties) of an entity.
|
|
590
|
+
|
|
591
|
+
Parameters
|
|
592
|
+
----------
|
|
593
|
+
uri: str
|
|
594
|
+
Entity URI of the source
|
|
595
|
+
auth_key: Optional[str]
|
|
596
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
597
|
+
timeout: int
|
|
598
|
+
Timeout for the request (default: 60 seconds)
|
|
599
|
+
max_retries: int
|
|
600
|
+
Maximum number of retries (default: 3)
|
|
601
|
+
backoff_factor: float
|
|
602
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
603
|
+
second try without a delay) (default: 0.1)
|
|
604
|
+
Returns
|
|
605
|
+
-------
|
|
606
|
+
relations: Dict[OntologyPropertyReference, ObjectProperty]
|
|
607
|
+
All relations a dict
|
|
608
|
+
|
|
609
|
+
Raises
|
|
610
|
+
------
|
|
611
|
+
WacomServiceException
|
|
612
|
+
If the graph service returns an error code
|
|
613
|
+
"""
|
|
614
|
+
if auth_key is None:
|
|
615
|
+
auth_key, _ = self.handle_token()
|
|
616
|
+
url: str = f"{self.service_base_url}{WacomKnowledgeService.ENTITY_ENDPOINT}/{urllib.parse.quote(uri)}/relations"
|
|
617
|
+
headers: dict = {USER_AGENT_HEADER_FLAG: self.user_agent, AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}"}
|
|
618
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
619
|
+
with requests.Session() as session:
|
|
620
|
+
retries: Retry = Retry(
|
|
621
|
+
total=max_retries, backoff_factor=backoff_factor, status_forcelist=[500, 502, 503, 504]
|
|
622
|
+
)
|
|
623
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
624
|
+
response: Response = session.get(url, headers=headers, timeout=timeout, verify=self.verify_calls)
|
|
625
|
+
if response.ok:
|
|
626
|
+
rel: list = response.json().get(RELATIONS_TAG)
|
|
627
|
+
return ObjectProperty.create_from_list(rel)
|
|
628
|
+
raise handle_error("Retrieving relations failed.", response)
|
|
629
|
+
|
|
630
|
+
def labels(
|
|
631
|
+
self,
|
|
632
|
+
uri: str,
|
|
633
|
+
locale: LocaleCode = EN_US,
|
|
634
|
+
auth_key: Optional[str] = None,
|
|
635
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
636
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
637
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
638
|
+
) -> List[Label]:
|
|
639
|
+
"""
|
|
640
|
+
Extract list labels of entity.
|
|
641
|
+
|
|
642
|
+
Parameters
|
|
643
|
+
----------
|
|
644
|
+
uri: str
|
|
645
|
+
Entity URI of the source
|
|
646
|
+
locale: LocaleCode [default:= EN_US]
|
|
647
|
+
ISO-3166 Country Codes and ISO-639 Language Codes in the format <language_code>_<country>, e.g., en_US.
|
|
648
|
+
auth_key: Optional[str] = None
|
|
649
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
650
|
+
timeout: int
|
|
651
|
+
Timeout for the request (default: 60 seconds)
|
|
652
|
+
max_retries: int
|
|
653
|
+
Maximum number of retries (default: 3)
|
|
654
|
+
backoff_factor: float
|
|
655
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
656
|
+
second try without a delay) (default: 0.1)
|
|
657
|
+
|
|
658
|
+
Returns
|
|
659
|
+
-------
|
|
660
|
+
labels: List[Label]
|
|
661
|
+
List of labels of an entity.
|
|
662
|
+
|
|
663
|
+
Raises
|
|
664
|
+
------
|
|
665
|
+
WacomServiceException
|
|
666
|
+
If the graph service returns an error code
|
|
667
|
+
"""
|
|
668
|
+
if auth_key is None:
|
|
669
|
+
auth_key, _ = self.handle_token()
|
|
670
|
+
url: str = f"{self.service_base_url}{WacomKnowledgeService.ENTITY_ENDPOINT}/{uri}/labels"
|
|
671
|
+
headers: dict = {USER_AGENT_HEADER_FLAG: self.user_agent, AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}"}
|
|
672
|
+
with requests.Session() as session:
|
|
673
|
+
retries: Retry = Retry(
|
|
674
|
+
total=max_retries, backoff_factor=backoff_factor, status_forcelist=[500, 502, 503, 504]
|
|
675
|
+
)
|
|
676
|
+
session.mount("https://", HTTPAdapter(max_retries=retries))
|
|
677
|
+
response: Response = session.get(
|
|
678
|
+
url, headers=headers, params={LOCALE_TAG: locale}, timeout=timeout, verify=self.verify_calls
|
|
679
|
+
)
|
|
680
|
+
if response.ok:
|
|
681
|
+
response_dict: dict = response.json()
|
|
682
|
+
if LABELS_TAG in response_dict:
|
|
683
|
+
return [Label.create_from_dict(label) for label in response_dict[LABELS_TAG]]
|
|
684
|
+
return []
|
|
685
|
+
raise handle_error("Retrieving labels failed.", response)
|
|
686
|
+
|
|
687
|
+
def literals(
|
|
688
|
+
self,
|
|
689
|
+
uri: str,
|
|
690
|
+
locale: LocaleCode = EN_US,
|
|
691
|
+
auth_key: Optional[str] = None,
|
|
692
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
693
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
694
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
695
|
+
) -> List[DataProperty]:
|
|
696
|
+
"""
|
|
697
|
+
Collect all literals of entity.
|
|
698
|
+
|
|
699
|
+
Parameters
|
|
700
|
+
----------
|
|
701
|
+
uri: str
|
|
702
|
+
Entity URI of the source
|
|
703
|
+
locale: LocaleCode [default:= EN_US]
|
|
704
|
+
ISO-3166 Country Codes and ISO-639 Language Codes in the format <language_code>_<country>, e.g., en_US.
|
|
705
|
+
auth_key: Optional[str] = None
|
|
706
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
707
|
+
timeout: int
|
|
708
|
+
Timeout for the request (default: 60 seconds)
|
|
709
|
+
max_retries: int
|
|
710
|
+
Maximum number of retries (default: 3)
|
|
711
|
+
backoff_factor: float
|
|
712
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
713
|
+
second try without a delay) (default: 0.1).
|
|
714
|
+
|
|
715
|
+
Returns
|
|
716
|
+
-------
|
|
717
|
+
labels: List[DataProperty]
|
|
718
|
+
List of data properties of an entity.
|
|
719
|
+
|
|
720
|
+
Raises
|
|
721
|
+
------
|
|
722
|
+
WacomServiceException
|
|
723
|
+
If the graph service returns an error code
|
|
724
|
+
"""
|
|
725
|
+
if auth_key is None:
|
|
726
|
+
auth_key, _ = self.handle_token()
|
|
727
|
+
url: str = f"{self.service_base_url}{WacomKnowledgeService.ENTITY_ENDPOINT}/{uri}/literals"
|
|
728
|
+
headers: dict = {USER_AGENT_HEADER_FLAG: self.user_agent, AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}"}
|
|
729
|
+
with requests.Session() as session:
|
|
730
|
+
retries: Retry = Retry(
|
|
731
|
+
total=max_retries, backoff_factor=backoff_factor, status_forcelist=[500, 502, 503, 504]
|
|
732
|
+
)
|
|
733
|
+
session.mount("https://", HTTPAdapter(max_retries=retries))
|
|
734
|
+
response: Response = session.get(
|
|
735
|
+
url, headers=headers, params={LOCALE_TAG: locale}, timeout=timeout, verify=self.verify_calls
|
|
736
|
+
)
|
|
737
|
+
if response.ok:
|
|
738
|
+
literals: list = response.json().get(DATA_PROPERTIES_TAG)
|
|
739
|
+
return DataProperty.create_from_list(literals)
|
|
740
|
+
raise handle_error(f"Failed to pull literals for {uri}.", response)
|
|
741
|
+
|
|
742
|
+
def create_relation(
|
|
743
|
+
self,
|
|
744
|
+
source: str,
|
|
745
|
+
relation: OntologyPropertyReference,
|
|
746
|
+
target: str,
|
|
747
|
+
auth_key: Optional[str] = None,
|
|
748
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
749
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
750
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
751
|
+
):
|
|
752
|
+
"""
|
|
753
|
+
Creates a relation for an entity to a source entity.
|
|
754
|
+
|
|
755
|
+
Parameters
|
|
756
|
+
----------
|
|
757
|
+
source: str
|
|
758
|
+
Entity URI of the source
|
|
759
|
+
relation: OntologyPropertyReference
|
|
760
|
+
ObjectProperty property
|
|
761
|
+
target: str
|
|
762
|
+
Entity URI of the target
|
|
763
|
+
auth_key: Optional[str] = None
|
|
764
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
765
|
+
timeout: int
|
|
766
|
+
Timeout for the request (default: 60 seconds)
|
|
767
|
+
max_retries: int
|
|
768
|
+
Maximum number of retries (default: 3)
|
|
769
|
+
backoff_factor: float
|
|
770
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
771
|
+
second try without a delay) (default: 0.1)
|
|
772
|
+
|
|
773
|
+
Raises
|
|
774
|
+
------
|
|
775
|
+
WacomServiceException
|
|
776
|
+
If the graph service returns an error code
|
|
777
|
+
"""
|
|
778
|
+
if auth_key is None:
|
|
779
|
+
auth_key, _ = self.handle_token()
|
|
780
|
+
url: str = f"{self.service_base_url}{WacomKnowledgeService.ENTITY_ENDPOINT}/{source}/relation"
|
|
781
|
+
headers: dict = {USER_AGENT_HEADER_FLAG: self.user_agent, AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}"}
|
|
782
|
+
params: dict = {RELATION_TAG: relation.iri, TARGET: target}
|
|
783
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
784
|
+
with requests.Session() as session:
|
|
785
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
786
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
787
|
+
response: Response = session.post(
|
|
788
|
+
url, params=params, headers=headers, timeout=timeout, verify=self.verify_calls
|
|
789
|
+
)
|
|
790
|
+
if not response.ok:
|
|
791
|
+
raise handle_error("Creation of relation failed.", response)
|
|
792
|
+
|
|
793
|
+
def create_relations_bulk(
|
|
794
|
+
self,
|
|
795
|
+
source: str,
|
|
796
|
+
relations: Dict[OntologyPropertyReference, List[str]],
|
|
797
|
+
auth_key: Optional[str] = None,
|
|
798
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
799
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
800
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
801
|
+
):
|
|
802
|
+
"""
|
|
803
|
+
Creates all the relations for an entity to a source entity.
|
|
804
|
+
|
|
805
|
+
Parameters
|
|
806
|
+
----------
|
|
807
|
+
source: str
|
|
808
|
+
Entity URI of the source
|
|
809
|
+
relations: Dict[OntologyPropertyReference, List[str]]
|
|
810
|
+
ObjectProperty property and targets mapping.
|
|
811
|
+
auth_key: Optional[str] = None
|
|
812
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
813
|
+
timeout: int
|
|
814
|
+
Timeout for the request (default: 60 seconds)
|
|
815
|
+
max_retries: int
|
|
816
|
+
Maximum number of retries (default: 3)
|
|
817
|
+
backoff_factor: float
|
|
818
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
819
|
+
second try without a delay) (default: 0.1)
|
|
820
|
+
|
|
821
|
+
Raises
|
|
822
|
+
------
|
|
823
|
+
WacomServiceException
|
|
824
|
+
If the graph service returns an error code
|
|
825
|
+
"""
|
|
826
|
+
if auth_key is None:
|
|
827
|
+
auth_key, _ = self.handle_token()
|
|
828
|
+
url: str = f"{self.service_base_url}{WacomKnowledgeService.ENTITY_ENDPOINT}/{source}/relations"
|
|
829
|
+
headers: dict = {USER_AGENT_HEADER_FLAG: self.user_agent, AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}"}
|
|
830
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
831
|
+
with requests.Session() as session:
|
|
832
|
+
retries: Retry = Retry(
|
|
833
|
+
total=max_retries, backoff_factor=backoff_factor, status_forcelist=[500, 502, 503, 504]
|
|
834
|
+
)
|
|
835
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
836
|
+
for updates in split_updates(relations):
|
|
837
|
+
response: Response = session.post(
|
|
838
|
+
url, timeout=timeout, json=updates, headers=headers, verify=self.verify_calls
|
|
839
|
+
)
|
|
840
|
+
if not response.ok:
|
|
841
|
+
raise handle_error("Creation of relation failed.", response, payload=updates)
|
|
842
|
+
|
|
843
|
+
def remove_relation(
|
|
844
|
+
self,
|
|
845
|
+
source: str,
|
|
846
|
+
relation: OntologyPropertyReference,
|
|
847
|
+
target: str,
|
|
848
|
+
auth_key: Optional[str] = None,
|
|
849
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
850
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
851
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
852
|
+
):
|
|
853
|
+
"""
|
|
854
|
+
Removes a relation.
|
|
855
|
+
|
|
856
|
+
Parameters
|
|
857
|
+
----------
|
|
858
|
+
source: str
|
|
859
|
+
Entity uri of the source
|
|
860
|
+
relation: OntologyPropertyReference
|
|
861
|
+
ObjectProperty property
|
|
862
|
+
target: str
|
|
863
|
+
Entity uri of the target
|
|
864
|
+
auth_key: Optional[str] = None
|
|
865
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
866
|
+
timeout: int
|
|
867
|
+
Timeout for the request (default: 60 seconds)
|
|
868
|
+
max_retries: int
|
|
869
|
+
Maximum number of retries (default: 3)
|
|
870
|
+
backoff_factor: float
|
|
871
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
872
|
+
second try without a delay) (default: 0.1)
|
|
873
|
+
|
|
874
|
+
Raises
|
|
875
|
+
------
|
|
876
|
+
WacomServiceException
|
|
877
|
+
If the graph service returns an error code
|
|
878
|
+
"""
|
|
879
|
+
if auth_key is None:
|
|
880
|
+
auth_key, _ = self.handle_token()
|
|
881
|
+
url: str = f"{self.service_base_url}{WacomKnowledgeService.ENTITY_ENDPOINT}/{source}/relation"
|
|
882
|
+
params: Dict[str, str] = {RELATION_TAG: relation.iri, TARGET: target}
|
|
883
|
+
headers: Dict[str, str] = {
|
|
884
|
+
USER_AGENT_HEADER_FLAG: self.user_agent,
|
|
885
|
+
AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}",
|
|
886
|
+
}
|
|
887
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
888
|
+
with requests.Session() as session:
|
|
889
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
890
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
891
|
+
# Get response
|
|
892
|
+
response: Response = session.delete(
|
|
893
|
+
url, params=params, headers=headers, timeout=timeout, verify=self.verify_calls
|
|
894
|
+
)
|
|
895
|
+
if not response.ok:
|
|
896
|
+
raise handle_error("Removal of relation failed.", response)
|
|
897
|
+
|
|
898
|
+
def activations(
|
|
899
|
+
self,
|
|
900
|
+
uris: List[str],
|
|
901
|
+
depth: int,
|
|
902
|
+
auth_key: Optional[str] = None,
|
|
903
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
904
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
905
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
906
|
+
) -> Tuple[Dict[str, ThingObject], List[Tuple[str, OntologyPropertyReference, str]]]:
|
|
907
|
+
"""
|
|
908
|
+
Spreading activation, retrieving the entities related to an entity.
|
|
909
|
+
|
|
910
|
+
Parameters
|
|
911
|
+
----------
|
|
912
|
+
uris: List[str]
|
|
913
|
+
List of URIS for entity.
|
|
914
|
+
depth: int
|
|
915
|
+
Depth of activations
|
|
916
|
+
auth_key: Optional[str] = None
|
|
917
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
918
|
+
timeout: int
|
|
919
|
+
Timeout for the request (default: 60 seconds)
|
|
920
|
+
max_retries: int
|
|
921
|
+
Maximum number of retries (default: 3)
|
|
922
|
+
backoff_factor: float
|
|
923
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
924
|
+
second try without a delay) (default: 0.1)
|
|
925
|
+
|
|
926
|
+
Returns
|
|
927
|
+
-------
|
|
928
|
+
entity_map: Dict[str, ThingObject]
|
|
929
|
+
Map with entity and its URI as key.
|
|
930
|
+
relations: List[Tuple[str, OntologyPropertyReference, str]]
|
|
931
|
+
List of relations with subject predicate, (Property), and subject
|
|
932
|
+
|
|
933
|
+
Raises
|
|
934
|
+
------
|
|
935
|
+
WacomServiceException
|
|
936
|
+
If the graph service returns an error code, and activation failed.
|
|
937
|
+
"""
|
|
938
|
+
if auth_key is None:
|
|
939
|
+
auth_key, _ = self.handle_token()
|
|
940
|
+
url: str = f"{self.service_base_url}{WacomKnowledgeService.ACTIVATIONS_ENDPOINT}"
|
|
941
|
+
|
|
942
|
+
headers: Dict[str, str] = {
|
|
943
|
+
USER_AGENT_HEADER_FLAG: self.user_agent,
|
|
944
|
+
AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}",
|
|
945
|
+
}
|
|
946
|
+
params: dict = {URIS_TAG: uris, ACTIVATION_TAG: depth}
|
|
947
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
948
|
+
with requests.Session() as session:
|
|
949
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
950
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
951
|
+
response: Response = session.get(
|
|
952
|
+
url, headers=headers, params=params, timeout=timeout, verify=self.verify_calls
|
|
953
|
+
)
|
|
954
|
+
if response.ok:
|
|
955
|
+
entities: Dict[str, Any] = response.json()
|
|
956
|
+
things: Dict[str, ThingObject] = {e[URI_TAG]: ThingObject.from_dict(e) for e in entities[ENTITIES_TAG]}
|
|
957
|
+
relations: List[Tuple[str, OntologyPropertyReference, str]] = []
|
|
958
|
+
for r in entities[RELATIONS_TAG]:
|
|
959
|
+
relation: OntologyPropertyReference = OntologyPropertyReference.parse(r[PREDICATE])
|
|
960
|
+
relations.append((r[SUBJECT], relation, r[OBJECT]))
|
|
961
|
+
if r[SUBJECT] in things:
|
|
962
|
+
things[r[SUBJECT]].add_relation(ObjectProperty(relation, outgoing=[r[OBJECT]]))
|
|
963
|
+
return things, relations
|
|
964
|
+
raise handle_error(f"Activation failed. uris:= {uris} activation:={depth}).", response)
|
|
965
|
+
|
|
966
|
+
def listing(
|
|
967
|
+
self,
|
|
968
|
+
filter_type: OntologyClassReference,
|
|
969
|
+
page_id: Optional[str] = None,
|
|
970
|
+
limit: int = 30,
|
|
971
|
+
locale: Optional[LocaleCode] = None,
|
|
972
|
+
visibility: Optional[Visibility] = None,
|
|
973
|
+
is_owner: Optional[bool] = None,
|
|
974
|
+
estimate_count: bool = False,
|
|
975
|
+
auth_key: Optional[str] = None,
|
|
976
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
977
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
978
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
979
|
+
) -> Tuple[List[ThingObject], int, str]:
|
|
980
|
+
"""
|
|
981
|
+
List all entities visible to users.
|
|
982
|
+
|
|
983
|
+
Parameters
|
|
984
|
+
----------
|
|
985
|
+
filter_type: OntologyClassReference
|
|
986
|
+
Filtering with entity
|
|
987
|
+
page_id: Optional[str]
|
|
988
|
+
Page id. Start from this page id
|
|
989
|
+
limit: int
|
|
990
|
+
Limit of the returned entities.
|
|
991
|
+
locale: Optional[LanguageCode] [default:=None]
|
|
992
|
+
ISO-3166 Country Codes and ISO-639 Language Codes in the format '<language_code>_<country>', e.g., en_US.
|
|
993
|
+
visibility: Optional[Visibility] [default:=None]
|
|
994
|
+
Filter the entities based on its visibilities
|
|
995
|
+
is_owner: Optional[bool] [default:=None]
|
|
996
|
+
Filter the entities based on its owner
|
|
997
|
+
estimate_count: bool [default:=False]
|
|
998
|
+
Request an estimate of the entities in a tenant.
|
|
999
|
+
auth_key: Optional[str] = None
|
|
1000
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
1001
|
+
timeout: int
|
|
1002
|
+
Timeout for the request (default: 60 seconds)
|
|
1003
|
+
max_retries: int
|
|
1004
|
+
Maximum number of retries
|
|
1005
|
+
backoff_factor: float
|
|
1006
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
1007
|
+
second try without a delay)
|
|
1008
|
+
|
|
1009
|
+
Returns
|
|
1010
|
+
-------
|
|
1011
|
+
entities: List[ThingObject]
|
|
1012
|
+
List of entities
|
|
1013
|
+
estimated_total_number: int
|
|
1014
|
+
Number of all entities
|
|
1015
|
+
next_page_id: str
|
|
1016
|
+
Identifier of the next page
|
|
1017
|
+
|
|
1018
|
+
Raises
|
|
1019
|
+
------
|
|
1020
|
+
WacomServiceException
|
|
1021
|
+
If the graph service returns an error code
|
|
1022
|
+
"""
|
|
1023
|
+
if auth_key is None:
|
|
1024
|
+
auth_key, _ = self.handle_token()
|
|
1025
|
+
url: str = f"{self.service_base_url}{WacomKnowledgeService.LISTING_ENDPOINT}"
|
|
1026
|
+
# Header with auth token
|
|
1027
|
+
headers: Dict[str, str] = {
|
|
1028
|
+
USER_AGENT_HEADER_FLAG: self.user_agent,
|
|
1029
|
+
AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}",
|
|
1030
|
+
}
|
|
1031
|
+
# Parameter with filtering and limit
|
|
1032
|
+
parameters: Dict[str, str] = {TYPE_TAG: filter_type.iri, LIMIT_PARAMETER: limit, ESTIMATE_COUNT: estimate_count}
|
|
1033
|
+
if locale:
|
|
1034
|
+
parameters[LOCALE_TAG] = locale
|
|
1035
|
+
if visibility:
|
|
1036
|
+
parameters[VISIBILITY_TAG] = str(visibility.value)
|
|
1037
|
+
if is_owner is not None:
|
|
1038
|
+
parameters[IS_OWNER_PARAM] = str(is_owner)
|
|
1039
|
+
# If filtering is configured
|
|
1040
|
+
if page_id is not None:
|
|
1041
|
+
parameters[NEXT_PAGE_ID_TAG] = page_id
|
|
1042
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
1043
|
+
with requests.Session() as session:
|
|
1044
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
1045
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
1046
|
+
# Send request
|
|
1047
|
+
response: Response = session.get(
|
|
1048
|
+
url, params=parameters, headers=headers, timeout=timeout, verify=self.verify_calls
|
|
1049
|
+
)
|
|
1050
|
+
# If response is successful
|
|
1051
|
+
if response.ok:
|
|
1052
|
+
entities_resp: dict = response.json()
|
|
1053
|
+
next_page_id: str = entities_resp[NEXT_PAGE_ID_TAG]
|
|
1054
|
+
estimated_total_number: int = entities_resp.get(TOTAL_COUNT, 0)
|
|
1055
|
+
entities: List[ThingObject] = []
|
|
1056
|
+
if LISTING in entities_resp:
|
|
1057
|
+
for e in entities_resp[LISTING]:
|
|
1058
|
+
thing: ThingObject = ThingObject.from_dict(e)
|
|
1059
|
+
thing.status_flag = EntityStatus.SYNCED
|
|
1060
|
+
entities.append(thing)
|
|
1061
|
+
return entities, estimated_total_number, next_page_id
|
|
1062
|
+
raise handle_error(f"Failed to list the entities (since:= {page_id}, limit:={limit}).", response)
|
|
1063
|
+
|
|
1064
|
+
def search_all(
|
|
1065
|
+
self,
|
|
1066
|
+
search_term: str,
|
|
1067
|
+
language_code: LocaleCode,
|
|
1068
|
+
types: List[OntologyClassReference],
|
|
1069
|
+
limit: int = 30,
|
|
1070
|
+
next_page_id: str = None,
|
|
1071
|
+
auth_key: Optional[str] = None,
|
|
1072
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
1073
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
1074
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
1075
|
+
) -> Tuple[List[ThingObject], str]:
|
|
1076
|
+
"""Search term in labels, literals and description.
|
|
1077
|
+
|
|
1078
|
+
Parameters
|
|
1079
|
+
----------
|
|
1080
|
+
auth_key: str
|
|
1081
|
+
Auth key from user
|
|
1082
|
+
search_term: str
|
|
1083
|
+
Search term.
|
|
1084
|
+
language_code: LocaleCode
|
|
1085
|
+
ISO-3166 Country Codes and ISO-639 Language Codes in the format '<language_code>_<country>', e.g., en_US.
|
|
1086
|
+
types: List[OntologyClassReference]
|
|
1087
|
+
Limits the types for search.
|
|
1088
|
+
limit: int (default:= 30)
|
|
1089
|
+
Size of the page for pagination.
|
|
1090
|
+
next_page_id: str (default:=None)
|
|
1091
|
+
ID of the next page within pagination.
|
|
1092
|
+
timeout: int
|
|
1093
|
+
Timeout for the request (default: 60 seconds)
|
|
1094
|
+
max_retries: int
|
|
1095
|
+
Maximum number of retries
|
|
1096
|
+
backoff_factor: float
|
|
1097
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
1098
|
+
second try without a delay)
|
|
1099
|
+
|
|
1100
|
+
Returns
|
|
1101
|
+
-------
|
|
1102
|
+
results: List[ThingObject]
|
|
1103
|
+
List of things matching the search term
|
|
1104
|
+
next_page_id: str
|
|
1105
|
+
ID of the next page.
|
|
1106
|
+
|
|
1107
|
+
Raises
|
|
1108
|
+
------
|
|
1109
|
+
WacomServiceException
|
|
1110
|
+
If the graph service returns an error code.
|
|
1111
|
+
"""
|
|
1112
|
+
if auth_key is None:
|
|
1113
|
+
auth_key, _ = self.handle_token()
|
|
1114
|
+
headers: Dict[str, str] = {
|
|
1115
|
+
USER_AGENT_HEADER_FLAG: self.user_agent,
|
|
1116
|
+
AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}",
|
|
1117
|
+
}
|
|
1118
|
+
parameters: Dict[str, Any] = {
|
|
1119
|
+
SEARCH_TERM: search_term,
|
|
1120
|
+
LANGUAGE_PARAMETER: language_code,
|
|
1121
|
+
TYPES_PARAMETER: [ot.iri for ot in types],
|
|
1122
|
+
LIMIT: limit,
|
|
1123
|
+
NEXT_PAGE_ID_TAG: next_page_id,
|
|
1124
|
+
}
|
|
1125
|
+
url: str = f"{self.service_base_url}{WacomKnowledgeService.SEARCH_TYPES_ENDPOINT}"
|
|
1126
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
1127
|
+
with requests.Session() as session:
|
|
1128
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
1129
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
1130
|
+
response: Response = session.get(
|
|
1131
|
+
url, headers=headers, params=parameters, timeout=timeout, verify=self.verify_calls
|
|
1132
|
+
)
|
|
1133
|
+
if response.ok:
|
|
1134
|
+
return WacomKnowledgeService.__search_results__(response.json())
|
|
1135
|
+
raise handle_error(f"Search on labels {search_term} failed. ", response)
|
|
1136
|
+
|
|
1137
|
+
def search_labels(
|
|
1138
|
+
self,
|
|
1139
|
+
search_term: str,
|
|
1140
|
+
language_code: LocaleCode,
|
|
1141
|
+
limit: int = 30,
|
|
1142
|
+
next_page_id: str = None,
|
|
1143
|
+
auth_key: Optional[str] = None,
|
|
1144
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
1145
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
1146
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
1147
|
+
) -> Tuple[List[ThingObject], str]:
|
|
1148
|
+
"""Search for matches in labels.
|
|
1149
|
+
|
|
1150
|
+
Parameters
|
|
1151
|
+
----------
|
|
1152
|
+
search_term: str
|
|
1153
|
+
Search term.
|
|
1154
|
+
language_code: LocaleCode
|
|
1155
|
+
ISO-3166 Country Codes and ISO-639 Language Codes in the format '<language_code>_<country>', e.g., en_US.
|
|
1156
|
+
limit: int (default:= 30)
|
|
1157
|
+
Size of the page for pagination.
|
|
1158
|
+
next_page_id: str (default:=None)
|
|
1159
|
+
ID of the next page within pagination.
|
|
1160
|
+
auth_key: Optional[str] = None
|
|
1161
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
1162
|
+
timeout: int
|
|
1163
|
+
Timeout for the request (default: 60 seconds)
|
|
1164
|
+
max_retries: int
|
|
1165
|
+
Maximum number of retries
|
|
1166
|
+
backoff_factor: float
|
|
1167
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
1168
|
+
second try without a delay)
|
|
1169
|
+
|
|
1170
|
+
Returns
|
|
1171
|
+
-------
|
|
1172
|
+
results: List[ThingObject]
|
|
1173
|
+
List of things matching the search term
|
|
1174
|
+
next_page_id: str
|
|
1175
|
+
ID of the next page.
|
|
1176
|
+
|
|
1177
|
+
Raises
|
|
1178
|
+
------
|
|
1179
|
+
WacomServiceException
|
|
1180
|
+
If the graph service returns an error code.
|
|
1181
|
+
"""
|
|
1182
|
+
if auth_key is None:
|
|
1183
|
+
auth_key, _ = self.handle_token()
|
|
1184
|
+
url: str = f"{self.service_base_url}{WacomKnowledgeService.SEARCH_LABELS_ENDPOINT}"
|
|
1185
|
+
headers: Dict[str, str] = {
|
|
1186
|
+
USER_AGENT_HEADER_FLAG: self.user_agent,
|
|
1187
|
+
AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}",
|
|
1188
|
+
}
|
|
1189
|
+
parameters: Dict[str, Any] = {
|
|
1190
|
+
SEARCH_TERM: search_term,
|
|
1191
|
+
LOCALE_TAG: language_code,
|
|
1192
|
+
LIMIT: limit,
|
|
1193
|
+
NEXT_PAGE_ID_TAG: next_page_id,
|
|
1194
|
+
}
|
|
1195
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
1196
|
+
with requests.Session() as session:
|
|
1197
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
1198
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
1199
|
+
response: Response = session.get(
|
|
1200
|
+
url, headers=headers, params=parameters, timeout=timeout, verify=self.verify_calls
|
|
1201
|
+
)
|
|
1202
|
+
if response.ok:
|
|
1203
|
+
return WacomKnowledgeService.__search_results__(response.json())
|
|
1204
|
+
raise handle_error(f"Search on labels {search_term} failed. ", response)
|
|
1205
|
+
|
|
1206
|
+
def search_literal(
|
|
1207
|
+
self,
|
|
1208
|
+
search_term: str,
|
|
1209
|
+
literal: OntologyPropertyReference,
|
|
1210
|
+
pattern: SearchPattern = SearchPattern.REGEX,
|
|
1211
|
+
language_code: LocaleCode = EN_US,
|
|
1212
|
+
limit: int = 30,
|
|
1213
|
+
next_page_id: str = None,
|
|
1214
|
+
auth_key: Optional[str] = None,
|
|
1215
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
1216
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
1217
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
1218
|
+
) -> Tuple[List[ThingObject], str]:
|
|
1219
|
+
"""
|
|
1220
|
+
Search for matches in literals.
|
|
1221
|
+
|
|
1222
|
+
Parameters
|
|
1223
|
+
----------
|
|
1224
|
+
search_term: str
|
|
1225
|
+
Search term.
|
|
1226
|
+
literal: OntologyPropertyReference
|
|
1227
|
+
Literal used for the search
|
|
1228
|
+
pattern: SearchPattern (default:= SearchPattern.REGEX)
|
|
1229
|
+
Search pattern. The chosen search pattern must fit the type of the entity.
|
|
1230
|
+
language_code: LocaleCode (default:= EN_US)
|
|
1231
|
+
ISO-3166 Country Codes and ISO-639 Language Codes in the format '<language_code>_<country>', e.g., en_US.
|
|
1232
|
+
limit: int (default:= 30)
|
|
1233
|
+
Size of the page for pagination.
|
|
1234
|
+
next_page_id: str (default:=None)
|
|
1235
|
+
ID of the next page within pagination.
|
|
1236
|
+
auth_key: Optional[str] = None
|
|
1237
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
1238
|
+
timeout: int
|
|
1239
|
+
Timeout for the request (default: 60 seconds)
|
|
1240
|
+
max_retries: int
|
|
1241
|
+
Maximum number of retries
|
|
1242
|
+
backoff_factor: float
|
|
1243
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
1244
|
+
second try without a delay)
|
|
1245
|
+
|
|
1246
|
+
Returns
|
|
1247
|
+
-------
|
|
1248
|
+
results: List[ThingObject]
|
|
1249
|
+
List of things matching the search term
|
|
1250
|
+
next_page_id: str
|
|
1251
|
+
ID of the next page.
|
|
1252
|
+
|
|
1253
|
+
Raises
|
|
1254
|
+
------
|
|
1255
|
+
WacomServiceException
|
|
1256
|
+
If the graph service returns an error code.
|
|
1257
|
+
"""
|
|
1258
|
+
if auth_key is None:
|
|
1259
|
+
auth_key, _ = self.handle_token()
|
|
1260
|
+
url: str = f"{self.service_base_url}{WacomKnowledgeService.SEARCH_LITERALS_ENDPOINT}"
|
|
1261
|
+
parameters: Dict[str, Any] = {
|
|
1262
|
+
VALUE: search_term,
|
|
1263
|
+
LITERAL_PARAMETER: literal.iri,
|
|
1264
|
+
LANGUAGE_PARAMETER: language_code,
|
|
1265
|
+
LIMIT_PARAMETER: limit,
|
|
1266
|
+
SEARCH_PATTERN_PARAMETER: pattern.value,
|
|
1267
|
+
NEXT_PAGE_ID_TAG: next_page_id,
|
|
1268
|
+
}
|
|
1269
|
+
headers: Dict[str, str] = {
|
|
1270
|
+
USER_AGENT_HEADER_FLAG: self.user_agent,
|
|
1271
|
+
AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}",
|
|
1272
|
+
}
|
|
1273
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
1274
|
+
with requests.Session() as session:
|
|
1275
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
1276
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
1277
|
+
response: Response = session.get(
|
|
1278
|
+
url, headers=headers, params=parameters, timeout=timeout, verify=self.verify_calls
|
|
1279
|
+
)
|
|
1280
|
+
if response.ok:
|
|
1281
|
+
return WacomKnowledgeService.__search_results__(response.json())
|
|
1282
|
+
raise handle_error(f"Search on literals {search_term} failed. ", response)
|
|
1283
|
+
|
|
1284
|
+
def search_relation(
|
|
1285
|
+
self,
|
|
1286
|
+
relation: OntologyPropertyReference,
|
|
1287
|
+
language_code: LocaleCode,
|
|
1288
|
+
subject_uri: str = None,
|
|
1289
|
+
object_uri: str = None,
|
|
1290
|
+
limit: int = 30,
|
|
1291
|
+
next_page_id: str = None,
|
|
1292
|
+
auth_key: Optional[str] = None,
|
|
1293
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
1294
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
1295
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
1296
|
+
) -> Tuple[List[ThingObject], str]:
|
|
1297
|
+
"""
|
|
1298
|
+
Search for matches in literals.
|
|
1299
|
+
|
|
1300
|
+
Parameters
|
|
1301
|
+
----------
|
|
1302
|
+
relation: OntologyPropertyReference
|
|
1303
|
+
Search term.
|
|
1304
|
+
language_code: LocaleCode
|
|
1305
|
+
ISO-3166 Country Codes and ISO-639 Language Codes in the format '<language_code>_<country>', e.g., en_US.
|
|
1306
|
+
subject_uri: str (default:=None)
|
|
1307
|
+
URI of the subject
|
|
1308
|
+
object_uri: str (default:=None)
|
|
1309
|
+
URI of the object
|
|
1310
|
+
limit: int (default:= 30)
|
|
1311
|
+
Size of the page for pagination.
|
|
1312
|
+
next_page_id: str (default:=None)
|
|
1313
|
+
ID of the next page within pagination.
|
|
1314
|
+
auth_key: Optional[str] = None
|
|
1315
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
1316
|
+
timeout: int
|
|
1317
|
+
Timeout for the request (default: 60 seconds)
|
|
1318
|
+
max_retries: int
|
|
1319
|
+
Maximum number of retries
|
|
1320
|
+
backoff_factor: float
|
|
1321
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
1322
|
+
second try without a delay)
|
|
1323
|
+
|
|
1324
|
+
Returns
|
|
1325
|
+
-------
|
|
1326
|
+
results: List[ThingObject]
|
|
1327
|
+
List of things matching the search term
|
|
1328
|
+
next_page_id: str
|
|
1329
|
+
ID of the next page.
|
|
1330
|
+
|
|
1331
|
+
Raises
|
|
1332
|
+
------
|
|
1333
|
+
WacomServiceException
|
|
1334
|
+
If the graph service returns an error code.
|
|
1335
|
+
"""
|
|
1336
|
+
if auth_key is None:
|
|
1337
|
+
auth_key, _ = self.handle_token()
|
|
1338
|
+
url: str = f"{self.service_base_url}{WacomKnowledgeService.SEARCH_RELATION_ENDPOINT}"
|
|
1339
|
+
parameters: Dict[str, Any] = {
|
|
1340
|
+
SUBJECT_URI: subject_uri,
|
|
1341
|
+
RELATION_URI: relation.iri,
|
|
1342
|
+
OBJECT_URI: object_uri,
|
|
1343
|
+
LANGUAGE_PARAMETER: language_code,
|
|
1344
|
+
LIMIT: limit,
|
|
1345
|
+
NEXT_PAGE_ID_TAG: next_page_id,
|
|
1346
|
+
}
|
|
1347
|
+
headers: Dict[str, str] = {
|
|
1348
|
+
USER_AGENT_HEADER_FLAG: self.user_agent,
|
|
1349
|
+
AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}",
|
|
1350
|
+
}
|
|
1351
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
1352
|
+
with requests.Session() as session:
|
|
1353
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
1354
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
1355
|
+
response: Response = session.get(
|
|
1356
|
+
url, headers=headers, params=parameters, timeout=timeout, verify=self.verify_calls
|
|
1357
|
+
)
|
|
1358
|
+
if response.ok:
|
|
1359
|
+
return WacomKnowledgeService.__search_results__(response.json())
|
|
1360
|
+
raise handle_error(
|
|
1361
|
+
f"Search on: subject:={subject_uri}, relation {relation.iri}, " f"object:= {object_uri} failed. ",
|
|
1362
|
+
response,
|
|
1363
|
+
)
|
|
1364
|
+
|
|
1365
|
+
def search_description(
|
|
1366
|
+
self,
|
|
1367
|
+
search_term: str,
|
|
1368
|
+
language_code: LocaleCode,
|
|
1369
|
+
limit: int = 30,
|
|
1370
|
+
next_page_id: str = None,
|
|
1371
|
+
auth_key: Optional[str] = None,
|
|
1372
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
1373
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
1374
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
1375
|
+
) -> Tuple[List[ThingObject], str]:
|
|
1376
|
+
"""Search for matches in description.
|
|
1377
|
+
|
|
1378
|
+
Parameters
|
|
1379
|
+
----------
|
|
1380
|
+
search_term: str
|
|
1381
|
+
Search term.
|
|
1382
|
+
language_code: LocaleCode
|
|
1383
|
+
ISO-3166 Country Codes and ISO-639 Language Codes in the format '<language_code>_<country>', e.g., en_US.
|
|
1384
|
+
limit: int (default:= 30)
|
|
1385
|
+
Size of the page for pagination.
|
|
1386
|
+
next_page_id: str (default:=None)
|
|
1387
|
+
ID of the next page within pagination.
|
|
1388
|
+
auth_key: Optional[str] = None
|
|
1389
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
1390
|
+
timeout: int
|
|
1391
|
+
Timeout for the request (default: 60 seconds)
|
|
1392
|
+
max_retries: int
|
|
1393
|
+
Maximum number of retries
|
|
1394
|
+
backoff_factor: float
|
|
1395
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
1396
|
+
second try without a delay)
|
|
1397
|
+
|
|
1398
|
+
Returns
|
|
1399
|
+
-------
|
|
1400
|
+
results: List[ThingObject]
|
|
1401
|
+
List of things matching the search term
|
|
1402
|
+
next_page_id: str
|
|
1403
|
+
ID of the next page.
|
|
1404
|
+
|
|
1405
|
+
Raises
|
|
1406
|
+
------
|
|
1407
|
+
WacomServiceException
|
|
1408
|
+
If the graph service returns an error code.
|
|
1409
|
+
"""
|
|
1410
|
+
if auth_key is None:
|
|
1411
|
+
auth_key, _ = self.handle_token()
|
|
1412
|
+
url: str = f"{self.service_base_url}{WacomKnowledgeService.SEARCH_DESCRIPTION_ENDPOINT}"
|
|
1413
|
+
parameters: Dict[str, Any] = {
|
|
1414
|
+
SEARCH_TERM: search_term,
|
|
1415
|
+
LOCALE_TAG: language_code,
|
|
1416
|
+
LIMIT: limit,
|
|
1417
|
+
NEXT_PAGE_ID_TAG: next_page_id,
|
|
1418
|
+
}
|
|
1419
|
+
headers: dict = {AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}", USER_AGENT_HEADER_FLAG: self.user_agent}
|
|
1420
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
1421
|
+
with requests.Session() as session:
|
|
1422
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
1423
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
1424
|
+
response: Response = session.get(
|
|
1425
|
+
url, headers=headers, params=parameters, timeout=timeout, verify=self.verify_calls
|
|
1426
|
+
)
|
|
1427
|
+
if response.ok:
|
|
1428
|
+
return WacomKnowledgeService.__search_results__(response.json())
|
|
1429
|
+
raise handle_error(f"Search on labels {search_term}@{language_code} failed. ", response)
|
|
1430
|
+
|
|
1431
|
+
@staticmethod
|
|
1432
|
+
def __search_results__(response: Dict[str, Any]) -> Tuple[List[ThingObject], str]:
|
|
1433
|
+
"""
|
|
1434
|
+
Convert response to list of ThingObjects and next page id.
|
|
1435
|
+
|
|
1436
|
+
Parameters
|
|
1437
|
+
----------
|
|
1438
|
+
response: Dict[str, Any]
|
|
1439
|
+
Response from the service.
|
|
1440
|
+
|
|
1441
|
+
Returns
|
|
1442
|
+
-------
|
|
1443
|
+
results: List[ThingObject]
|
|
1444
|
+
List of things matching the search term
|
|
1445
|
+
next_page_id: str
|
|
1446
|
+
ID of the next page.
|
|
1447
|
+
"""
|
|
1448
|
+
results: List[ThingObject] = []
|
|
1449
|
+
for elem in response["result"]:
|
|
1450
|
+
results.append(ThingObject.from_dict(elem))
|
|
1451
|
+
return results, response[NEXT_PAGE_ID_TAG]
|
|
1452
|
+
|
|
1453
|
+
def set_entity_image_local(
|
|
1454
|
+
self,
|
|
1455
|
+
entity_uri: str,
|
|
1456
|
+
path: Path,
|
|
1457
|
+
auth_key: Optional[str] = None,
|
|
1458
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
1459
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
1460
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
1461
|
+
) -> str:
|
|
1462
|
+
"""Setting the image of the entity.
|
|
1463
|
+
The image is stored locally.
|
|
1464
|
+
|
|
1465
|
+
Parameters
|
|
1466
|
+
----------
|
|
1467
|
+
entity_uri: str
|
|
1468
|
+
URI of the entity.
|
|
1469
|
+
path: Path
|
|
1470
|
+
The path of image.
|
|
1471
|
+
auth_key: Optional[str] = None
|
|
1472
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
1473
|
+
timeout: int
|
|
1474
|
+
Timeout for the request (default: 60 seconds)
|
|
1475
|
+
max_retries: int
|
|
1476
|
+
Maximum number of retries
|
|
1477
|
+
backoff_factor: float
|
|
1478
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
1479
|
+
second try without a delay)
|
|
1480
|
+
|
|
1481
|
+
Returns
|
|
1482
|
+
-------
|
|
1483
|
+
image_id: str
|
|
1484
|
+
ID of uploaded image
|
|
1485
|
+
|
|
1486
|
+
Raises
|
|
1487
|
+
------
|
|
1488
|
+
WacomServiceException
|
|
1489
|
+
If the graph service returns an error code.
|
|
1490
|
+
"""
|
|
1491
|
+
with path.open("rb") as fp:
|
|
1492
|
+
image_bytes: bytes = fp.read()
|
|
1493
|
+
file_name: str = str(path.absolute())
|
|
1494
|
+
_, file_extension = os.path.splitext(file_name.lower())
|
|
1495
|
+
mime_type = MIME_TYPE[file_extension]
|
|
1496
|
+
return self.set_entity_image(
|
|
1497
|
+
entity_uri,
|
|
1498
|
+
image_bytes,
|
|
1499
|
+
file_name,
|
|
1500
|
+
mime_type,
|
|
1501
|
+
auth_key=auth_key,
|
|
1502
|
+
timeout=timeout,
|
|
1503
|
+
max_retries=max_retries,
|
|
1504
|
+
backoff_factor=backoff_factor,
|
|
1505
|
+
)
|
|
1506
|
+
|
|
1507
|
+
def set_entity_image_url(
|
|
1508
|
+
self,
|
|
1509
|
+
entity_uri: str,
|
|
1510
|
+
image_url: str,
|
|
1511
|
+
file_name: Optional[str] = None,
|
|
1512
|
+
mime_type: Optional[str] = None,
|
|
1513
|
+
auth_key: Optional[str] = None,
|
|
1514
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
1515
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
1516
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
1517
|
+
) -> str:
|
|
1518
|
+
"""Setting the image of the entity.
|
|
1519
|
+
The image for the URL is downloaded and then pushed to the backend.
|
|
1520
|
+
|
|
1521
|
+
Parameters
|
|
1522
|
+
----------
|
|
1523
|
+
auth_key: str
|
|
1524
|
+
Auth key from user
|
|
1525
|
+
entity_uri: str
|
|
1526
|
+
URI of the entity.
|
|
1527
|
+
image_url: str
|
|
1528
|
+
URL of the image.
|
|
1529
|
+
file_name: str (default:=None)
|
|
1530
|
+
Name of the file. If None the name is extracted from URL.
|
|
1531
|
+
mime_type: str (default:=None)
|
|
1532
|
+
Mime type.
|
|
1533
|
+
auth_key: Optional[str] = None
|
|
1534
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
1535
|
+
timeout: int
|
|
1536
|
+
Timeout for the request (default: 60 seconds)
|
|
1537
|
+
max_retries: int
|
|
1538
|
+
Maximum number of retries
|
|
1539
|
+
backoff_factor: float
|
|
1540
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
1541
|
+
second try without a delay)
|
|
1542
|
+
Returns
|
|
1543
|
+
-------
|
|
1544
|
+
image_id: str
|
|
1545
|
+
ID of uploaded image
|
|
1546
|
+
|
|
1547
|
+
Raises
|
|
1548
|
+
------
|
|
1549
|
+
WacomServiceException
|
|
1550
|
+
If the graph service returns an error code.
|
|
1551
|
+
"""
|
|
1552
|
+
mount_point: str = "https://" if image_url.startswith("https") else "http://"
|
|
1553
|
+
with requests.Session() as session:
|
|
1554
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
1555
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
1556
|
+
headers: Dict[str, str] = {USER_AGENT_HEADER_FLAG: self.user_agent}
|
|
1557
|
+
response: Response = session.get(image_url, headers=headers, timeout=timeout, verify=self.verify_calls)
|
|
1558
|
+
if response.ok:
|
|
1559
|
+
image_bytes: bytes = response.content
|
|
1560
|
+
file_name: str = image_url if file_name is None else file_name
|
|
1561
|
+
if mime_type is None:
|
|
1562
|
+
_, file_extension = os.path.splitext(file_name.lower())
|
|
1563
|
+
if file_extension not in MIME_TYPE:
|
|
1564
|
+
raise handle_error(
|
|
1565
|
+
"Creation of entity image failed. Mime-type cannot be identified or is not " "supported.",
|
|
1566
|
+
response,
|
|
1567
|
+
)
|
|
1568
|
+
mime_type = MIME_TYPE[file_extension]
|
|
1569
|
+
|
|
1570
|
+
return self.set_entity_image(
|
|
1571
|
+
entity_uri,
|
|
1572
|
+
image_bytes,
|
|
1573
|
+
file_name,
|
|
1574
|
+
mime_type,
|
|
1575
|
+
auth_key=auth_key,
|
|
1576
|
+
timeout=timeout,
|
|
1577
|
+
max_retries=max_retries,
|
|
1578
|
+
backoff_factor=backoff_factor,
|
|
1579
|
+
)
|
|
1580
|
+
raise handle_error("Creation of entity image failed.", response)
|
|
1581
|
+
|
|
1582
|
+
def set_entity_image(
|
|
1583
|
+
self,
|
|
1584
|
+
entity_uri: str,
|
|
1585
|
+
image_byte: bytes,
|
|
1586
|
+
file_name: str = "icon.jpg",
|
|
1587
|
+
mime_type: str = "image/jpeg",
|
|
1588
|
+
auth_key: Optional[str] = None,
|
|
1589
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
1590
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
1591
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
1592
|
+
) -> str:
|
|
1593
|
+
"""Setting the image of the entity.
|
|
1594
|
+
The image for the URL is downloaded and then pushed to the backend.
|
|
1595
|
+
|
|
1596
|
+
Parameters
|
|
1597
|
+
----------
|
|
1598
|
+
entity_uri: str
|
|
1599
|
+
URI of the entity.
|
|
1600
|
+
image_byte: bytes
|
|
1601
|
+
Binary encoded image.
|
|
1602
|
+
file_name: str (default:=None)
|
|
1603
|
+
Name of the file. If None the name is extracted from URL.
|
|
1604
|
+
mime_type: str (default:=None)
|
|
1605
|
+
Mime type.
|
|
1606
|
+
auth_key: Optional[str] = None
|
|
1607
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
1608
|
+
timeout: int
|
|
1609
|
+
Timeout for the request (default: 60 seconds)
|
|
1610
|
+
max_retries: int
|
|
1611
|
+
Maximum number of retries
|
|
1612
|
+
backoff_factor: float
|
|
1613
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
1614
|
+
second try without a delay)
|
|
1615
|
+
|
|
1616
|
+
Returns
|
|
1617
|
+
-------
|
|
1618
|
+
image_id: str
|
|
1619
|
+
ID of uploaded image
|
|
1620
|
+
|
|
1621
|
+
Raises
|
|
1622
|
+
------
|
|
1623
|
+
WacomServiceException
|
|
1624
|
+
If the graph service returns an error code.
|
|
1625
|
+
"""
|
|
1626
|
+
if auth_key is None:
|
|
1627
|
+
auth_key, _ = self.handle_token()
|
|
1628
|
+
headers: dict = {AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}", USER_AGENT_HEADER_FLAG: self.user_agent}
|
|
1629
|
+
files: List[Tuple[str, Tuple[str, bytes, str]]] = [("file", (file_name, image_byte, mime_type))]
|
|
1630
|
+
url: str = f"{self.service_base_url}{self.ENTITY_IMAGE_ENDPOINT}{urllib.parse.quote(entity_uri)}"
|
|
1631
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
1632
|
+
with requests.Session() as session:
|
|
1633
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
1634
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
1635
|
+
response: Response = session.patch(
|
|
1636
|
+
url, headers=headers, files=files, timeout=timeout, verify=self.verify_calls
|
|
1637
|
+
)
|
|
1638
|
+
if response.ok:
|
|
1639
|
+
return response.json()["imageId"]
|
|
1640
|
+
raise handle_error("Creation of entity image failed.", response)
|
|
1641
|
+
|
|
1642
|
+
def import_entities(
|
|
1643
|
+
self,
|
|
1644
|
+
entities: List[ThingObject],
|
|
1645
|
+
auth_key: Optional[str] = None,
|
|
1646
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
1647
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
1648
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
1649
|
+
) -> str:
|
|
1650
|
+
"""Import entities to the graph.
|
|
1651
|
+
|
|
1652
|
+
Parameters
|
|
1653
|
+
----------
|
|
1654
|
+
entities: List[ThingObject]
|
|
1655
|
+
List of entities to import.
|
|
1656
|
+
auth_key: Optional[str] = None
|
|
1657
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
1658
|
+
timeout: int
|
|
1659
|
+
Timeout for the request (default: 60 seconds)
|
|
1660
|
+
max_retries: int
|
|
1661
|
+
Maximum number of retries
|
|
1662
|
+
backoff_factor: float
|
|
1663
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
1664
|
+
second try without a delay)
|
|
1665
|
+
|
|
1666
|
+
Returns
|
|
1667
|
+
-------
|
|
1668
|
+
job_id: str
|
|
1669
|
+
ID of the job
|
|
1670
|
+
|
|
1671
|
+
Raises
|
|
1672
|
+
------
|
|
1673
|
+
WacomServiceException
|
|
1674
|
+
If the graph service returns an error code.
|
|
1675
|
+
"""
|
|
1676
|
+
if auth_key is None:
|
|
1677
|
+
auth_key, _ = self.handle_token()
|
|
1678
|
+
headers: dict = {USER_AGENT_HEADER_FLAG: self.user_agent, AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}"}
|
|
1679
|
+
ndjson_lines: List[str] = []
|
|
1680
|
+
for obj in entities:
|
|
1681
|
+
data_dict = obj.__import_format_dict__()
|
|
1682
|
+
ndjson_lines.append(json.dumps(data_dict)) # Convert each dict to a JSON string
|
|
1683
|
+
|
|
1684
|
+
ndjson_content = "\n".join(ndjson_lines) # Join JSON strings with newline
|
|
1685
|
+
|
|
1686
|
+
# Compress the NDJSON string to a gzip byte array
|
|
1687
|
+
compressed_data: bytes = gzip.compress(ndjson_content.encode("utf-8"))
|
|
1688
|
+
with open("import.gzip", "wb") as f:
|
|
1689
|
+
f.write(compressed_data)
|
|
1690
|
+
files: List[Tuple[str, Tuple[str, bytes, str]]] = [
|
|
1691
|
+
("file", ("import.njson", compressed_data, "application/x-gzip"))
|
|
1692
|
+
]
|
|
1693
|
+
url: str = f"{self.service_base_url}{self.IMPORT_ENTITIES_ENDPOINT}"
|
|
1694
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
1695
|
+
with requests.Session() as session:
|
|
1696
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
1697
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
1698
|
+
response: Response = session.post(
|
|
1699
|
+
url, headers=headers, files=files, timeout=timeout, verify=self.verify_calls
|
|
1700
|
+
)
|
|
1701
|
+
if response.ok:
|
|
1702
|
+
return response.json()["jobId"]
|
|
1703
|
+
raise handle_error("Import endpoint returns an error.", response)
|
|
1704
|
+
|
|
1705
|
+
def job_status(
|
|
1706
|
+
self,
|
|
1707
|
+
job_id: str,
|
|
1708
|
+
auth_key: Optional[str] = None,
|
|
1709
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
1710
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
1711
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
1712
|
+
) -> Dict[str, Any]:
|
|
1713
|
+
"""
|
|
1714
|
+
Retrieve the status of the job.
|
|
1715
|
+
|
|
1716
|
+
Parameters
|
|
1717
|
+
----------
|
|
1718
|
+
job_id: str
|
|
1719
|
+
ID of the job
|
|
1720
|
+
auth_key: Optional[str] = None
|
|
1721
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
1722
|
+
timeout: int
|
|
1723
|
+
Timeout for the request (default: 60 seconds)
|
|
1724
|
+
max_retries: int
|
|
1725
|
+
Maximum number of retries
|
|
1726
|
+
backoff_factor: float
|
|
1727
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
1728
|
+
second try without a delay)
|
|
1729
|
+
|
|
1730
|
+
Returns
|
|
1731
|
+
-------
|
|
1732
|
+
job_status: Dict[str, Any]
|
|
1733
|
+
Status of the job
|
|
1734
|
+
"""
|
|
1735
|
+
if auth_key is None:
|
|
1736
|
+
auth_key, _ = self.handle_token()
|
|
1737
|
+
headers: dict = {USER_AGENT_HEADER_FLAG: self.user_agent, AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}"}
|
|
1738
|
+
url: str = f"{self.service_base_url}{self.IMPORT_ENTITIES_ENDPOINT}/{job_id}"
|
|
1739
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
1740
|
+
with requests.Session() as session:
|
|
1741
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
1742
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
1743
|
+
response: Response = session.get(url, headers=headers, timeout=timeout, verify=self.verify_calls)
|
|
1744
|
+
if response.ok:
|
|
1745
|
+
return response.json()
|
|
1746
|
+
raise handle_error(f"Retrieving job status for {job_id} failed.", response)
|
|
1747
|
+
|
|
1748
|
+
# ------------------------------------ Admin endpoints -------------------------------------------------------------
|
|
1749
|
+
|
|
1750
|
+
def rebuild_vector_search_index(
|
|
1751
|
+
self,
|
|
1752
|
+
prune: bool = False,
|
|
1753
|
+
auth_key: Optional[str] = None,
|
|
1754
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
1755
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
1756
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
1757
|
+
):
|
|
1758
|
+
"""
|
|
1759
|
+
Rebuild the vector search index.
|
|
1760
|
+
|
|
1761
|
+
**Remark:**
|
|
1762
|
+
Works for users with role 'TenantAdmin'.
|
|
1763
|
+
|
|
1764
|
+
Parameters
|
|
1765
|
+
----------
|
|
1766
|
+
prune: bool
|
|
1767
|
+
Prune the index before rebuilding.
|
|
1768
|
+
auth_key: Optional[str] = None
|
|
1769
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
1770
|
+
timeout: int
|
|
1771
|
+
Timeout for the request (default: 60 seconds)
|
|
1772
|
+
max_retries: int
|
|
1773
|
+
Maximum number of retries (default: 3)
|
|
1774
|
+
backoff_factor: float
|
|
1775
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
1776
|
+
second try without a delay)
|
|
1777
|
+
"""
|
|
1778
|
+
url: str = f"{self.service_base_url}{WacomKnowledgeService.REBUILD_VECTOR_SEARCH_INDEX}"
|
|
1779
|
+
params: Dict[str, str] = {PRUNE_PARAM: prune}
|
|
1780
|
+
if UserRole.ADMIN.value not in self.current_session.roles:
|
|
1781
|
+
raise WacomServiceException('Only users with role "Admin" can rebuild the vector search index.')
|
|
1782
|
+
if auth_key is None:
|
|
1783
|
+
auth_key, _ = self.handle_token()
|
|
1784
|
+
headers: Dict[str, str] = {
|
|
1785
|
+
USER_AGENT_HEADER_FLAG: self.user_agent,
|
|
1786
|
+
AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}",
|
|
1787
|
+
}
|
|
1788
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
1789
|
+
with requests.Session() as session:
|
|
1790
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
1791
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
1792
|
+
response: Response = session.post(
|
|
1793
|
+
url, params=params, headers=headers, timeout=timeout, verify=self.verify_calls
|
|
1794
|
+
)
|
|
1795
|
+
if not response.ok:
|
|
1796
|
+
raise handle_error("Rebuilding vector search index failed.", response)
|
|
1797
|
+
|
|
1798
|
+
def rebuild_nel_index(
|
|
1799
|
+
self,
|
|
1800
|
+
nel_index: Literal["western", "japanese"],
|
|
1801
|
+
prune: bool = False,
|
|
1802
|
+
auth_key: Optional[str] = None,
|
|
1803
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
1804
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
1805
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
1806
|
+
):
|
|
1807
|
+
"""
|
|
1808
|
+
Rebuild the named entity linking index.
|
|
1809
|
+
|
|
1810
|
+
**Remark:**
|
|
1811
|
+
Works for users with role 'TenantAdmin'
|
|
1812
|
+
|
|
1813
|
+
Parameters
|
|
1814
|
+
----------
|
|
1815
|
+
nel_index: Literal['western', 'japanese']
|
|
1816
|
+
Named entity linking index to rebuild.
|
|
1817
|
+
prune: bool
|
|
1818
|
+
Prune the index before rebuilding.
|
|
1819
|
+
auth_key: Optional[str] = None
|
|
1820
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
1821
|
+
timeout: int
|
|
1822
|
+
Timeout for the request (default: 60 seconds)
|
|
1823
|
+
max_retries: int
|
|
1824
|
+
Maximum number of retries
|
|
1825
|
+
backoff_factor: float
|
|
1826
|
+
A backoff factor to apply between attempts after.
|
|
1827
|
+
|
|
1828
|
+
Raises
|
|
1829
|
+
------
|
|
1830
|
+
WacomServiceException
|
|
1831
|
+
If the graph service returns an error code.
|
|
1832
|
+
"""
|
|
1833
|
+
url: str = f"{self.service_base_url}{WacomKnowledgeService.REBUILD_NEL_INDEX}"
|
|
1834
|
+
params: Dict[str, str] = {PRUNE_PARAM: prune, NEL_PARAM: nel_index}
|
|
1835
|
+
if auth_key is None:
|
|
1836
|
+
auth_key, _ = self.handle_token()
|
|
1837
|
+
if UserRole.ADMIN.value not in self.current_session.roles:
|
|
1838
|
+
raise WacomServiceException('Only users with role "Admin" can rebuild the vector search index.')
|
|
1839
|
+
auth_key, _ = self.handle_token()
|
|
1840
|
+
headers: Dict[str, str] = {
|
|
1841
|
+
USER_AGENT_HEADER_FLAG: self.user_agent,
|
|
1842
|
+
AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}",
|
|
1843
|
+
}
|
|
1844
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
1845
|
+
with requests.Session() as session:
|
|
1846
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
1847
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
1848
|
+
response: Response = session.post(
|
|
1849
|
+
url, params=params, headers=headers, timeout=timeout, verify=self.verify_calls
|
|
1850
|
+
)
|
|
1851
|
+
if not response.ok:
|
|
1852
|
+
raise handle_error("Rebuilding vector search index failed.", response)
|
|
1853
|
+
|
|
1854
|
+
def ontology_update(
|
|
1855
|
+
self,
|
|
1856
|
+
fix: bool = False,
|
|
1857
|
+
auth_key: Optional[str] = None,
|
|
1858
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
1859
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
1860
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
1861
|
+
):
|
|
1862
|
+
"""
|
|
1863
|
+
Update the ontology.
|
|
1864
|
+
|
|
1865
|
+
**Remark:**
|
|
1866
|
+
Works for users with role 'TenantAdmin'.
|
|
1867
|
+
|
|
1868
|
+
Parameters
|
|
1869
|
+
----------
|
|
1870
|
+
fix: bool [default:=False]
|
|
1871
|
+
Fix the ontology if tenant is in inconsistent state.
|
|
1872
|
+
auth_key: Optional[str] = None
|
|
1873
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
1874
|
+
timeout: int
|
|
1875
|
+
Timeout for the request (default: 60 seconds)
|
|
1876
|
+
max_retries: int
|
|
1877
|
+
Maximum number of retries
|
|
1878
|
+
backoff_factor: float
|
|
1879
|
+
A backoff factor to apply between attempts after the second try.
|
|
1880
|
+
|
|
1881
|
+
Raises
|
|
1882
|
+
------
|
|
1883
|
+
WacomServiceException
|
|
1884
|
+
If the graph service returns an error code and commit failed.
|
|
1885
|
+
"""
|
|
1886
|
+
if auth_key is None:
|
|
1887
|
+
auth_key, _ = self.handle_token()
|
|
1888
|
+
url: str = f'{self.service_base_url}{WacomKnowledgeService.ONTOLOGY_UPDATE_ENDPOINT}{"/fix" if fix else ""}'
|
|
1889
|
+
# Header with auth token
|
|
1890
|
+
headers: dict = {USER_AGENT_HEADER_FLAG: self.user_agent, AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}"}
|
|
1891
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
1892
|
+
with requests.Session() as session:
|
|
1893
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
1894
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
1895
|
+
response: Response = session.patch(url, headers=headers, timeout=timeout, verify=self.verify_calls)
|
|
1896
|
+
if not response.ok:
|
|
1897
|
+
raise handle_error("Ontology update fails.", response)
|