personal_knowledge_library 3.3.1__tar.gz → 3.4.0__tar.gz

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.

Files changed (46) hide show
  1. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/PKG-INFO +1 -1
  2. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/__init__.py +1 -1
  3. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/base/ontology.py +5 -5
  4. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/base/response.py +6 -6
  5. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/base/search.py +15 -4
  6. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/nel/base.py +0 -1
  7. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/public/helper.py +13 -4
  8. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/public/wikidata.py +1 -1
  9. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/services/asyncio/base.py +1 -1
  10. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/services/asyncio/graph.py +92 -61
  11. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/services/asyncio/group.py +78 -23
  12. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/services/asyncio/search.py +64 -18
  13. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/services/asyncio/users.py +30 -11
  14. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/services/base.py +6 -6
  15. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/services/graph.py +11 -5
  16. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/services/helper.py +0 -7
  17. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/services/ontology.py +3 -2
  18. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/services/search.py +11 -1
  19. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/services/tenant.py +2 -18
  20. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/services/users.py +2 -2
  21. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/utils/graph.py +23 -14
  22. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/pyproject.toml +1 -1
  23. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/LICENSE +0 -0
  24. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/README.md +0 -0
  25. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/base/__init__.py +0 -0
  26. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/base/access.py +0 -0
  27. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/base/entity.py +0 -0
  28. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/base/language.py +0 -0
  29. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/base/tenant.py +0 -0
  30. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/nel/__init__.py +0 -0
  31. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/nel/engine.py +0 -0
  32. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/ontomapping/__init__.py +0 -0
  33. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/ontomapping/manager.py +0 -0
  34. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/public/__init__.py +0 -0
  35. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/public/cache.py +0 -0
  36. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/public/client.py +0 -0
  37. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/public/relations.py +0 -0
  38. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/services/__init__.py +0 -0
  39. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/services/asyncio/__init__.py +0 -0
  40. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/services/group.py +0 -0
  41. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/services/session.py +0 -0
  42. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/utils/__init__.py +0 -0
  43. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/utils/diff.py +0 -0
  44. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/utils/import_format.py +0 -0
  45. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/utils/wikidata.py +0 -0
  46. {personal_knowledge_library-3.3.1 → personal_knowledge_library-3.4.0}/knowledge/utils/wikipedia.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: personal_knowledge_library
3
- Version: 3.3.1
3
+ Version: 3.4.0
4
4
  Summary: Library to access Wacom's Personal Knowledge graph.
5
5
  License-Expression: Apache-2.0
6
6
  License-File: LICENSE
@@ -17,7 +17,7 @@ __license__ = "Wacom"
17
17
  __maintainer__ = ["Markus Weber"]
18
18
  __email__ = "markus.weber@wacom.com"
19
19
  __status__ = "beta"
20
- __version__ = "3.3.1"
20
+ __version__ = "3.4.0"
21
21
 
22
22
  import loguru
23
23
 
@@ -997,12 +997,12 @@ class OntologyProperty(OntologyObject):
997
997
  return self.__reference
998
998
 
999
999
  @property
1000
- def subproperty_of(self) -> OntologyPropertyReference:
1000
+ def subproperty_of(self) -> Optional[OntologyPropertyReference]:
1001
1001
  """Reference to the super property"""
1002
1002
  return self.__subproperty_of
1003
1003
 
1004
1004
  @property
1005
- def inverse_property_of(self) -> OntologyPropertyReference:
1005
+ def inverse_property_of(self) -> Optional[OntologyPropertyReference]:
1006
1006
  """Reference to the inverse property"""
1007
1007
  return self.__inverse_property_of
1008
1008
 
@@ -1494,7 +1494,7 @@ class Ontology:
1494
1494
  return f"<Ontology> : classes:= {self.classes}"
1495
1495
 
1496
1496
 
1497
- class ThingObject(object):
1497
+ class ThingObject:
1498
1498
  """
1499
1499
  ThingObject
1500
1500
  -----------
@@ -2199,7 +2199,7 @@ class ThingObject(object):
2199
2199
  dict_object[TARGETS_TAG].append(INDEXING_VECTOR_SEARCH_TARGET)
2200
2200
  if self.use_vector_index_document:
2201
2201
  dict_object[TARGETS_TAG].append(INDEXING_VECTOR_SEARCH_DOCUMENT_TARGET)
2202
- if not self.use_full_text_index:
2202
+ if self.use_full_text_index:
2203
2203
  dict_object[TARGETS_TAG].append(INDEXING_FULLTEXT_TARGET)
2204
2204
  if external_user_id:
2205
2205
  dict_object[EXTERNAL_USER_ID_TAG] = external_user_id
@@ -2260,7 +2260,7 @@ class ThingObject(object):
2260
2260
  use_nel: bool = entity.get(USE_NEL_TAG, False)
2261
2261
  use_vector_index: bool = entity.get(USE_VECTOR_INDEX_TAG, False)
2262
2262
  use_vector_index_document: bool = entity.get(USE_VECTOR_DOCUMENT_INDEX_TAG, False)
2263
- use_full_text_index: bool = entity.get(USE_FULLTEXT_TAG, True)
2263
+ use_full_text_index: bool = entity.get(USE_FULLTEXT_TAG, False)
2264
2264
  # Vector index target
2265
2265
  if INDEXING_VECTOR_SEARCH_TARGET in entity.get(TARGETS_TAG, []):
2266
2266
  use_vector_index = True
@@ -324,19 +324,19 @@ class NewEntityUrisResponse:
324
324
 
325
325
  Parameters
326
326
  ----------
327
- new_entities_uris: List[str]
328
- The list of URIs of new entities.
327
+ new_entities_uris: Dict[str, str]
328
+ The mapping of entity IDs to URIs (ref_id -> uri).
329
329
  next_page_id: Optional[str]
330
330
  Next page ID for pagination.
331
331
  """
332
332
 
333
- def __init__(self, new_entities_uris: List[str], next_page_id: Optional[str]):
334
- self._new_entities_uris: List[str] = new_entities_uris
333
+ def __init__(self, new_entities_uris: List[Dict[str, str]], next_page_id: Optional[str]):
334
+ self._new_entities_uris: Dict[str, str] = {entry["ref_id"]: entry["uri"] for entry in new_entities_uris}
335
335
  self._next_page_id: Optional[str] = next_page_id
336
336
 
337
337
  @property
338
- def new_entities_uris(self) -> List[str]:
339
- """The list the uris of new entities."""
338
+ def new_entities_uris(self) -> Dict[str, str]:
339
+ """The mapping of entity IDs to URIs."""
340
340
  return self._new_entities_uris
341
341
 
342
342
  @property
@@ -435,12 +435,23 @@ class LabelMatchingResponse:
435
435
 
436
436
  class VectorDBDocument:
437
437
  """
438
- VectorDBDocument
439
- ================
440
- SegmentedContent model for the vector database.
438
+ Represents a document stored in a vector database.
441
439
 
442
- Properties
440
+ This class is used for handling documents with associated metadata within a vector
441
+ database. It provides properties to access the document's ID, content, URI, and
442
+ metadata, making it suitable for systems that manage search or retrieval of
443
+ semantic data in vectorized form.
444
+
445
+ Attributes
443
446
  ----------
447
+ id : str
448
+ A unique identifier for the document.
449
+ content : str
450
+ The textual content of the document.
451
+ uri : str
452
+ A URI associated with the document.
453
+ metadata : Dict[str, Any]
454
+ Additional metadata associated with the document.
444
455
  """
445
456
 
446
457
  def __init__(self, data: Dict[str, Any]):
@@ -181,7 +181,6 @@ class KnowledgeGraphEntity(NamedEntity):
181
181
  entity_type: EntityType = EntityType.PUBLIC_ENTITY,
182
182
  tokens: Optional[List[str]] = None,
183
183
  token_indexes: Optional[List[int]] = None,
184
-
185
184
  ):
186
185
  super().__init__(ref_text, start_idx, end_idx, entity_type)
187
186
  self.__source: EntitySource = source
@@ -12,7 +12,7 @@ from requests import Response
12
12
  from requests.adapters import HTTPAdapter
13
13
  from urllib3 import Retry
14
14
 
15
- from knowledge import logger
15
+ from knowledge import logger, __version__
16
16
  from knowledge.public import DEFAULT_MAX_RETRIES, DEFAULT_TIMEOUT, DEFAULT_BACKOFF_FACTOR, STATUS_FORCE_LIST
17
17
 
18
18
 
@@ -96,6 +96,14 @@ WIKIDATA_SPARQL_URL: str = "https://query.wikidata.org/sparql"
96
96
  WIKIDATA_SEARCH_URL: str = "https://www.wikidata.org/w/api.php"
97
97
 
98
98
 
99
+ def user_agent() -> str:
100
+ """User agent."""
101
+ return (
102
+ f"Personal Knowledge Library(Public Knowledge Crawler)/{__version__}"
103
+ f"(+https://github.com/Wacom-Developer/personal-knowledge-library)"
104
+ )
105
+
106
+
99
107
  # --------------------------------------- Helper functions -------------------------------------------------------------
100
108
  def image_url(img: str, dpi: int = 500):
101
109
  """
@@ -301,6 +309,7 @@ def __waiting_request__(
301
309
  status_forcelist=STATUS_FORCE_LIST, # HTTP status codes to retry on
302
310
  respect_retry_after_header=True, # respect the Retry-After header
303
311
  )
312
+ header: Dict[str, str] = {"User-Agent": user_agent()}
304
313
 
305
314
  # Create a session and mount the retry adapter
306
315
  with requests.Session() as session:
@@ -308,7 +317,7 @@ def __waiting_request__(
308
317
  session.mount("https://", retry_adapter)
309
318
 
310
319
  # Make a request using the session
311
- response: Response = session.get(url, timeout=timeout)
320
+ response: Response = session.get(url, headers=header, timeout=timeout)
312
321
 
313
322
  # Check the response status code
314
323
  if not response.ok:
@@ -364,7 +373,7 @@ def __waiting_multi_request__(
364
373
  )
365
374
  query: str = "|".join(checked_entity_ids)
366
375
  url: str = f"{base_url}{query}&format=json"
367
-
376
+ header: Dict[str, str] = {"User-Agent": user_agent()}
368
377
  # Define the retry policy
369
378
  retry_policy: Retry = Retry(
370
379
  total=max_retries, # maximum number of retries
@@ -379,7 +388,7 @@ def __waiting_multi_request__(
379
388
  session.mount("https://", retry_adapter)
380
389
 
381
390
  # Make a request using the session
382
- response: Response = session.get(url, timeout=timeout)
391
+ response: Response = session.get(url, headers=header, timeout=timeout)
383
392
 
384
393
  # Check the response status code
385
394
  if not response.ok:
@@ -877,7 +877,7 @@ class WikidataThing:
877
877
  val = {"tabular": data_value["value"]}
878
878
  elif data_type == "entity-schema":
879
879
  val = {"id": data_value["value"]["id"]}
880
- elif data_type in ["wikibase-form", "musical-notation"]:
880
+ elif data_type in {"wikibase-form", "musical-notation"}:
881
881
  continue
882
882
  else:
883
883
  raise WikiDataAPIException(f"Data type: {data_type} not supported.")
@@ -286,7 +286,7 @@ class AsyncServiceAPIClient(RESTAPIClient):
286
286
  session: aiohttp.ClientSession
287
287
  Asynchronous session
288
288
  """
289
- timeout: ClientTimeout = ClientTimeout(total=60)
289
+ timeout: ClientTimeout = ClientTimeout(total=DEFAULT_TIMEOUT)
290
290
  ssl_context: ssl.SSLContext = ssl.create_default_context(cafile=certifi.where())
291
291
  connector: aiohttp.TCPConnector = aiohttp.TCPConnector(ssl=ssl_context, resolver=cached_resolver)
292
292
  return aiohttp.ClientSession(
@@ -119,6 +119,7 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
119
119
  ONTOLOGY_UPDATE_ENDPOINT: str = "ontology-update"
120
120
  IMPORT_ENTITIES_ENDPOINT: str = "import"
121
121
  IMPORT_ERROR_LOG_ENDPOINT: str = "import/errorlog"
122
+ MAX_NUMBER_URIS: int = 40
122
123
 
123
124
  def __init__(
124
125
  self,
@@ -185,8 +186,13 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
185
186
  thing: ThingObject = ThingObject.from_dict(e)
186
187
  return thing
187
188
 
188
- async def entities(self, uris: List[str], locale: Optional[LocaleCode] = None, auth_key: Optional[str] = None) \
189
- -> List[ThingObject]:
189
+ async def entities(
190
+ self,
191
+ uris: List[str],
192
+ locale: Optional[LocaleCode] = None,
193
+ auth_key: Optional[str] = None,
194
+ timeout: int = DEFAULT_TIMEOUT,
195
+ ) -> List[ThingObject]:
190
196
  """
191
197
  Retrieve entities information from personal knowledge, using the URI as identifier.
192
198
 
@@ -200,6 +206,8 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
200
206
  ISO-3166 Country Codes and ISO-639 Language Codes in the format <language_code>_<country>, e.g., en_US.
201
207
  auth_key: Optional[str]
202
208
  Use a different auth key than the one from the client
209
+ timeout: int
210
+ Timeout in seconds. Default: 10 seconds.
203
211
 
204
212
  Returns
205
213
  -------
@@ -219,23 +227,25 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
219
227
  AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}",
220
228
  }
221
229
  things: List[ThingObject] = []
222
- params: Dict[str, Any] = {
223
- URIS_TAG: uris
224
- }
225
- if locale:
226
- params[LOCALE_TAG] = locale
230
+
227
231
  async with AsyncServiceAPIClient.__async_session__() as session:
228
- async with session.get(url, headers=headers, params=params, verify_ssl=self.verify_calls) as response:
229
- if response.ok:
230
- entities: List[Dict[str, Any]] = await response.json()
231
- for e in entities:
232
- thing: ThingObject = ThingObject.from_dict(e)
233
- things.append(thing)
234
- else:
235
- raise await handle_error(
236
- f"Retrieving of entities content failed. List of URIs: {uris}.", response,
237
- headers=headers
238
- )
232
+ for chunk in range(0, len(uris), AsyncWacomKnowledgeService.MAX_NUMBER_URIS):
233
+ subset = uris[chunk : chunk + AsyncWacomKnowledgeService.MAX_NUMBER_URIS]
234
+ params: Dict[str, Any] = {URIS_TAG: subset}
235
+ if locale:
236
+ params[LOCALE_TAG] = locale
237
+ async with session.get(
238
+ url, headers=headers, params=params, timeout=timeout, verify_ssl=self.verify_calls
239
+ ) as response:
240
+ if response.ok:
241
+ entities: List[Dict[str, Any]] = await response.json()
242
+ for e in entities:
243
+ thing: ThingObject = ThingObject.from_dict(e)
244
+ things.append(thing)
245
+ else:
246
+ raise await handle_error(
247
+ f"Retrieving of entities content failed. List of URIs: {uris}.", response, headers=headers
248
+ )
239
249
  await asyncio.sleep(0.25 if self.use_graceful_shutdown else 0.0)
240
250
  # Create ThingObject
241
251
  return things
@@ -594,10 +604,7 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
594
604
  return uri
595
605
 
596
606
  async def import_entities(
597
- self,
598
- entities: List[ThingObject],
599
- auth_key: Optional[str] = None,
600
- timeout: int = DEFAULT_TIMEOUT
607
+ self, entities: List[ThingObject], auth_key: Optional[str] = None, timeout: int = DEFAULT_TIMEOUT
601
608
  ) -> str:
602
609
  """Import entities to the graph.
603
610
 
@@ -645,10 +652,7 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
645
652
  raise await handle_error("Import endpoint returns an error.", response)
646
653
 
647
654
  async def import_entities_from_file(
648
- self,
649
- file_path: Path,
650
- auth_key: Optional[str] = None,
651
- timeout: int = DEFAULT_TIMEOUT
655
+ self, file_path: Path, auth_key: Optional[str] = None, timeout: int = DEFAULT_TIMEOUT
652
656
  ) -> str:
653
657
  """Import entities from a file to the graph.
654
658
 
@@ -670,6 +674,8 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
670
674
  ------
671
675
  WacomServiceException
672
676
  If the graph service returns an error code.
677
+ FileNotFoundError
678
+ If the file path does not exist.
673
679
  """
674
680
  if not file_path.exists():
675
681
  raise FileNotFoundError(f"The file {file_path} does not exist.")
@@ -680,12 +686,11 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
680
686
  # Compress the NDJSON string to a gzip byte array
681
687
  compressed_data: bytes = file.read()
682
688
  data: aiohttp.FormData = aiohttp.FormData()
683
- data.add_field("file", compressed_data, filename="import.njson.gz",
684
- content_type="application/x-gzip")
689
+ data.add_field("file", compressed_data, filename="import.njson.gz", content_type="application/x-gzip")
685
690
  url: str = f"{self.service_base_url}{self.IMPORT_ENTITIES_ENDPOINT}"
686
691
  async with AsyncServiceAPIClient.__async_session__() as session:
687
692
  async with session.post(
688
- url, headers=headers, data=data, timeout=timeout, verify_ssl=self.verify_calls
693
+ url, headers=headers, data=data, timeout=timeout, verify_ssl=self.verify_calls
689
694
  ) as response:
690
695
  if response.ok:
691
696
  structure: Dict[str, Any] = await response.json(loads=orjson.loads)
@@ -693,10 +698,7 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
693
698
  raise await handle_error("Import endpoint returns an error.", response)
694
699
 
695
700
  async def job_status(
696
- self,
697
- job_id: str,
698
- auth_key: Optional[str] = None,
699
- timeout: int = DEFAULT_TIMEOUT
701
+ self, job_id: str, auth_key: Optional[str] = None, timeout: int = DEFAULT_TIMEOUT
700
702
  ) -> JobStatus:
701
703
  """
702
704
  Retrieve the status of the job.
@@ -720,20 +722,18 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
720
722
  headers: dict = {USER_AGENT_HEADER_FLAG: self.user_agent, AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}"}
721
723
  url: str = f"{self.service_base_url}{self.IMPORT_ENTITIES_ENDPOINT}/{job_id}"
722
724
  async with AsyncServiceAPIClient.__async_session__() as session:
723
- async with session.get(
724
- url, headers=headers, timeout=timeout, verify_ssl=self.verify_calls
725
- ) as response:
725
+ async with session.get(url, headers=headers, timeout=timeout, verify_ssl=self.verify_calls) as response:
726
726
  if response.ok:
727
727
  structure: Dict[str, Any] = await response.json(loads=orjson.loads)
728
728
  return JobStatus.from_dict(structure)
729
729
  raise await handle_error(f"Retrieving job status for {job_id} failed.", response, headers=headers)
730
730
 
731
731
  async def import_error_log(
732
- self,
733
- job_id: str,
734
- auth_key: Optional[str] = None,
735
- next_page_id: Optional[str] = None,
736
- timeout: int = DEFAULT_TIMEOUT
732
+ self,
733
+ job_id: str,
734
+ auth_key: Optional[str] = None,
735
+ next_page_id: Optional[str] = None,
736
+ timeout: int = DEFAULT_TIMEOUT,
737
737
  ) -> ErrorLogResponse:
738
738
  """
739
739
  Retrieve the error log of the job.
@@ -761,7 +761,7 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
761
761
  params: Dict[str, str] = {NEXT_PAGE_ID_TAG: next_page_id} if next_page_id else {}
762
762
  async with AsyncServiceAPIClient.__async_session__() as session:
763
763
  async with session.get(
764
- url, headers=headers, params=params, timeout=timeout, verify_ssl=self.verify_calls
764
+ url, headers=headers, params=params, timeout=timeout, verify_ssl=self.verify_calls
765
765
  ) as response:
766
766
  if response.ok:
767
767
  structure: Dict[str, Any] = await response.json(loads=orjson.loads)
@@ -769,11 +769,11 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
769
769
  raise await handle_error(f"Retrieving job status for {job_id} failed.", response)
770
770
 
771
771
  async def import_new_uris(
772
- self,
773
- job_id: str,
774
- auth_key: Optional[str] = None,
775
- next_page_id: Optional[str] = None,
776
- timeout: int = DEFAULT_TIMEOUT
772
+ self,
773
+ job_id: str,
774
+ auth_key: Optional[str] = None,
775
+ next_page_id: Optional[str] = None,
776
+ timeout: int = DEFAULT_TIMEOUT,
777
777
  ) -> NewEntityUrisResponse:
778
778
  """
779
779
  Retrieve the new entity uris from the job.
@@ -801,15 +801,14 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
801
801
  params: Dict[str, str] = {NEXT_PAGE_ID_TAG: next_page_id} if next_page_id else {}
802
802
  async with AsyncServiceAPIClient.__async_session__() as session:
803
803
  async with session.get(
804
- url, headers=headers, params=params, timeout=timeout, verify_ssl=self.verify_calls
804
+ url, headers=headers, params=params, timeout=timeout, verify_ssl=self.verify_calls
805
805
  ) as response:
806
806
  if response.ok:
807
807
  structure: Dict[str, Any] = await response.json(loads=orjson.loads)
808
808
  return NewEntityUrisResponse.from_dict(structure)
809
809
  raise await handle_error(f"Retrieving job status for {job_id} failed.", response)
810
810
 
811
-
812
- async def update_entity(self, entity: ThingObject, auth_key: Optional[str] = None):
811
+ async def update_entity(self, entity: ThingObject, auth_key: Optional[str] = None, timeout: int = DEFAULT_TIMEOUT):
813
812
  """
814
813
  Updates entity in graph.
815
814
 
@@ -819,6 +818,8 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
819
818
  entity object
820
819
  auth_key: Optional[str]
821
820
  Use a different auth key than the one from the client
821
+ timeout: int
822
+ Timeout in seconds. Default: 10 seconds.
822
823
 
823
824
  Raises
824
825
  ------
@@ -838,7 +839,11 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
838
839
  payload: Dict[str, Any] = await AsyncWacomKnowledgeService.__entity__(entity)
839
840
  async with AsyncServiceAPIClient.__async_session__() as session:
840
841
  async with session.patch(
841
- url, json=payload, headers=headers, timeout=DEFAULT_TIMEOUT, verify_ssl=self.verify_calls
842
+ url,
843
+ json=payload,
844
+ headers=headers,
845
+ timeout=timeout,
846
+ verify_ssl=self.verify_calls,
842
847
  ) as response:
843
848
  if not response.ok:
844
849
  raise await handle_error(
@@ -962,7 +967,7 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
962
967
  return response_dict
963
968
 
964
969
  async def relations(
965
- self, uri: str, auth_key: Optional[str] = None
970
+ self, uri: str, auth_key: Optional[str] = None, timeout: int = DEFAULT_TIMEOUT
966
971
  ) -> Dict[OntologyPropertyReference, ObjectProperty]:
967
972
  """
968
973
  Retrieve the relations (object properties) of an entity.
@@ -975,6 +980,9 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
975
980
  auth_key: Optional[str]
976
981
  Use a different auth key than the one from the client
977
982
 
983
+ timeout: int
984
+ Request timeout in seconds (default: 60 seconds)
985
+
978
986
  Returns
979
987
  -------
980
988
  relations: Dict[OntologyPropertyReference, ObjectProperty]
@@ -996,7 +1004,7 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
996
1004
  AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}",
997
1005
  }
998
1006
  async with AsyncServiceAPIClient.__async_session__() as session:
999
- async with session.get(url, headers=headers, verify_ssl=self.verify_calls) as response:
1007
+ async with session.get(url, headers=headers, verify_ssl=self.verify_calls, timeout=timeout) as response:
1000
1008
  if response.ok:
1001
1009
  rel: list = (await response.json(loads=orjson.loads)).get(RELATIONS_TAG)
1002
1010
  else:
@@ -1131,7 +1139,11 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
1131
1139
  await asyncio.sleep(0.250 if self.use_graceful_shutdown else 0)
1132
1140
 
1133
1141
  async def create_relations_bulk(
1134
- self, source: str, relations: Dict[OntologyPropertyReference, List[str]], auth_key: Optional[str] = None
1142
+ self,
1143
+ source: str,
1144
+ relations: Dict[OntologyPropertyReference, List[str]],
1145
+ auth_key: Optional[str] = None,
1146
+ timeout: int = DEFAULT_TIMEOUT,
1135
1147
  ):
1136
1148
  """
1137
1149
  Creates all the relations for an entity to a source entity.
@@ -1147,6 +1159,9 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
1147
1159
  auth_key: Optional[str] = None
1148
1160
  If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
1149
1161
 
1162
+ timeout: int
1163
+ Request timeout in seconds (default: 60 seconds)
1164
+
1150
1165
  Raises
1151
1166
  ------
1152
1167
  WacomServiceException
@@ -1159,7 +1174,7 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
1159
1174
  async with AsyncServiceAPIClient.__async_session__() as session:
1160
1175
  for update_bulk in split_updates(relations):
1161
1176
  async with session.post(
1162
- url, json=update_bulk, headers=headers, verify_ssl=self.verify_calls
1177
+ url, json=update_bulk, headers=headers, verify_ssl=self.verify_calls, timeout=timeout
1163
1178
  ) as response:
1164
1179
  if not response.ok:
1165
1180
  raise await handle_error(
@@ -1171,7 +1186,12 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
1171
1186
  await asyncio.sleep(0.250 if self.use_graceful_shutdown else 0)
1172
1187
 
1173
1188
  async def remove_relation(
1174
- self, source: str, relation: OntologyPropertyReference, target: str, auth_key: Optional[str] = None
1189
+ self,
1190
+ source: str,
1191
+ relation: OntologyPropertyReference,
1192
+ target: str,
1193
+ auth_key: Optional[str] = None,
1194
+ timeout: int = DEFAULT_TIMEOUT,
1175
1195
  ):
1176
1196
  """
1177
1197
  Removes a relation.
@@ -1186,6 +1206,8 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
1186
1206
  Entities uri of the target
1187
1207
  auth_key: Optional[str] [default:=None]
1188
1208
  Use a different auth key than the one from the client
1209
+ timeout: int
1210
+ Request timeout in seconds (default: 60 seconds)
1189
1211
 
1190
1212
  Raises
1191
1213
  ------
@@ -1202,7 +1224,7 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
1202
1224
  }
1203
1225
  async with AsyncServiceAPIClient.__async_session__() as session:
1204
1226
  async with session.delete(
1205
- url, params=params, headers=headers, timeout=DEFAULT_TIMEOUT, verify_ssl=self.verify_calls
1227
+ url, params=params, headers=headers, timeout=timeout, verify_ssl=self.verify_calls
1206
1228
  ) as response:
1207
1229
  if not response.ok:
1208
1230
  raise await handle_error(
@@ -1211,7 +1233,7 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
1211
1233
  await asyncio.sleep(0.250 if self.use_graceful_shutdown else 0)
1212
1234
 
1213
1235
  async def activations(
1214
- self, uris: List[str], depth: int, auth_key: Optional[str] = None
1236
+ self, uris: List[str], depth: int, auth_key: Optional[str] = None, timeout: int = DEFAULT_TIMEOUT
1215
1237
  ) -> Tuple[Dict[str, ThingObject], List[Tuple[str, OntologyPropertyReference, str]]]:
1216
1238
  """
1217
1239
  Spreading activation, retrieving the entities related to an entity.
@@ -1224,6 +1246,8 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
1224
1246
  Depth of activations
1225
1247
  auth_key: Optional[str] [default:=None]
1226
1248
  Use a different auth key than the one from the client
1249
+ timeout: int
1250
+ Request timeout in seconds (default: 60 seconds)
1227
1251
 
1228
1252
  Returns
1229
1253
  -------
@@ -1247,7 +1271,9 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
1247
1271
  params: dict = {URIS_TAG: uris, ACTIVATION_TAG: depth}
1248
1272
 
1249
1273
  async with AsyncServiceAPIClient.__async_session__() as session:
1250
- async with session.get(url, headers=headers, params=params, verify_ssl=self.verify_calls) as response:
1274
+ async with session.get(
1275
+ url, headers=headers, params=params, verify_ssl=self.verify_calls, timeout=timeout
1276
+ ) as response:
1251
1277
  if response.ok:
1252
1278
  entities: Dict[str, Any] = await response.json(loads=orjson.loads)
1253
1279
  things: Dict[str, ThingObject] = {
@@ -1276,6 +1302,7 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
1276
1302
  is_owner: Optional[bool] = None,
1277
1303
  estimate_count: bool = False,
1278
1304
  auth_key: Optional[str] = None,
1305
+ timeout: int = DEFAULT_TIMEOUT,
1279
1306
  ) -> Tuple[List[ThingObject], int, str]:
1280
1307
  """
1281
1308
  List all entities visible to users.
@@ -1298,6 +1325,8 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
1298
1325
  Request an estimate of the entities in a tenant.
1299
1326
  auth_key: Optional[str]
1300
1327
  Auth key from user if not set, the client auth key will be used
1328
+ timeout: int
1329
+ Timeout for the request (default: 60 seconds)
1301
1330
 
1302
1331
  Returns
1303
1332
  -------
@@ -1338,7 +1367,9 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
1338
1367
  parameters[NEXT_PAGE_ID_TAG] = page_id
1339
1368
  async with AsyncServiceAPIClient.__async_session__() as session:
1340
1369
  # Send request
1341
- async with session.get(url, params=parameters, headers=headers, verify_ssl=self.verify_calls) as response:
1370
+ async with session.get(
1371
+ url, params=parameters, headers=headers, verify_ssl=self.verify_calls, timeout=timeout
1372
+ ) as response:
1342
1373
  # If response is successful
1343
1374
  if response.ok:
1344
1375
  entities_resp: Dict[str, Any] = await response.json(loads=orjson.loads)
@@ -1400,7 +1431,7 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
1400
1431
  next_page_id: str = None,
1401
1432
  auth_key: Optional[str] = None,
1402
1433
  ) -> Tuple[List[ThingObject], str]:
1403
- """Search term in labels, literals and description.
1434
+ """Search term in labels, literals, and description.
1404
1435
 
1405
1436
  Parameters
1406
1437
  ----------