personal_knowledge_library 3.2.2__tar.gz → 3.3.1__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.
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/PKG-INFO +4 -3
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/__init__.py +1 -1
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/base/ontology.py +1 -1
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/nel/base.py +19 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/nel/engine.py +2 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/asyncio/graph.py +223 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/graph.py +59 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/pyproject.toml +1 -1
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/LICENSE +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/README.md +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/base/__init__.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/base/access.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/base/entity.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/base/language.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/base/response.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/base/search.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/base/tenant.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/nel/__init__.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/ontomapping/__init__.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/ontomapping/manager.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/public/__init__.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/public/cache.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/public/client.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/public/helper.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/public/relations.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/public/wikidata.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/__init__.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/asyncio/__init__.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/asyncio/base.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/asyncio/group.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/asyncio/search.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/asyncio/users.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/base.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/group.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/helper.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/ontology.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/search.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/session.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/tenant.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/users.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/utils/__init__.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/utils/diff.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/utils/graph.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/utils/import_format.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/utils/wikidata.py +0 -0
- {personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/utils/wikipedia.py +0 -0
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: personal_knowledge_library
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.3.1
|
|
4
4
|
Summary: Library to access Wacom's Personal Knowledge graph.
|
|
5
|
-
License: Apache-2.0
|
|
5
|
+
License-Expression: Apache-2.0
|
|
6
|
+
License-File: LICENSE
|
|
6
7
|
Keywords: semantic-knowledge,knowledge-graph
|
|
7
8
|
Author: Markus Weber
|
|
8
9
|
Author-email: markus.weber@wacom.com
|
|
@@ -162,6 +162,10 @@ class KnowledgeGraphEntity(NamedEntity):
|
|
|
162
162
|
List of ontology types (class names)
|
|
163
163
|
entity_type: EntityType
|
|
164
164
|
Type of the entity.
|
|
165
|
+
tokens: Optional[List[str]] (default:=None)
|
|
166
|
+
List of tokens used to identify the entity.
|
|
167
|
+
token_indexes: Optional[List[int]] (default:=None)
|
|
168
|
+
List of token indexes used to identify the entity.
|
|
165
169
|
"""
|
|
166
170
|
|
|
167
171
|
def __init__(
|
|
@@ -175,6 +179,9 @@ class KnowledgeGraphEntity(NamedEntity):
|
|
|
175
179
|
content_link: str,
|
|
176
180
|
ontology_types: List[str],
|
|
177
181
|
entity_type: EntityType = EntityType.PUBLIC_ENTITY,
|
|
182
|
+
tokens: Optional[List[str]] = None,
|
|
183
|
+
token_indexes: Optional[List[int]] = None,
|
|
184
|
+
|
|
178
185
|
):
|
|
179
186
|
super().__init__(ref_text, start_idx, end_idx, entity_type)
|
|
180
187
|
self.__source: EntitySource = source
|
|
@@ -185,6 +192,8 @@ class KnowledgeGraphEntity(NamedEntity):
|
|
|
185
192
|
self.__thumbnail: Optional[str] = None
|
|
186
193
|
self.__ontology_types: List[str] = ontology_types
|
|
187
194
|
self.__relevant_type: OntologyClassReference = THING_CLASS
|
|
195
|
+
self.__tokens: Optional[List[str]] = tokens
|
|
196
|
+
self.__token_indexes: Optional[List[int]] = token_indexes
|
|
188
197
|
|
|
189
198
|
@property
|
|
190
199
|
def entity_source(self) -> EntitySource:
|
|
@@ -242,6 +251,16 @@ class KnowledgeGraphEntity(NamedEntity):
|
|
|
242
251
|
def relevant_type(self, value: OntologyClassReference):
|
|
243
252
|
self.__relevant_type = value
|
|
244
253
|
|
|
254
|
+
@property
|
|
255
|
+
def tokens(self) -> Optional[List[str]]:
|
|
256
|
+
"""List of tokens used to identify the entity."""
|
|
257
|
+
return self.__tokens
|
|
258
|
+
|
|
259
|
+
@property
|
|
260
|
+
def token_indexes(self) -> Optional[List[int]]:
|
|
261
|
+
"""List of token indexes used to identify the entity."""
|
|
262
|
+
return self.__token_indexes
|
|
263
|
+
|
|
245
264
|
def __repr__(self):
|
|
246
265
|
return f"{self.ref_text} [{self.start_idx}-{self.end_idx}] -> {self.entity_source} [{self.entity_type}]"
|
|
247
266
|
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/nel/engine.py
RENAMED
|
@@ -116,6 +116,8 @@ class WacomEntityLinkingEngine(PersonalEntityLinkingProcessor):
|
|
|
116
116
|
content_link="",
|
|
117
117
|
ontology_types=entity_types,
|
|
118
118
|
entity_type=EntityType.PERSONAL_ENTITY,
|
|
119
|
+
tokens=e.get("tokens"),
|
|
120
|
+
token_indexes=e.get("tokenIndexes"),
|
|
119
121
|
)
|
|
120
122
|
ne.relevant_type = OntologyClassReference.parse(e["type"])
|
|
121
123
|
named_entities.append(ne)
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
2
|
# Copyright © 2024-present Wacom. All rights reserved.
|
|
3
3
|
import asyncio
|
|
4
|
+
import gzip
|
|
5
|
+
import json
|
|
4
6
|
import logging
|
|
5
7
|
import os
|
|
6
8
|
import urllib
|
|
@@ -35,6 +37,7 @@ from knowledge.base.ontology import (
|
|
|
35
37
|
OntologyClassReference,
|
|
36
38
|
ObjectProperty,
|
|
37
39
|
)
|
|
40
|
+
from knowledge.base.response import JobStatus, ErrorLogResponse, NewEntityUrisResponse
|
|
38
41
|
from knowledge.nel.base import KnowledgeGraphEntity, EntityType, KnowledgeSource, EntitySource
|
|
39
42
|
from knowledge.services import AUTHORIZATION_HEADER_FLAG, IS_OWNER_PARAM, IndexType
|
|
40
43
|
from knowledge.services import (
|
|
@@ -114,6 +117,8 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
|
|
|
114
117
|
SEARCH_DESCRIPTION_ENDPOINT: str = "semantic-search/description"
|
|
115
118
|
SEARCH_RELATION_ENDPOINT: str = "semantic-search/relation"
|
|
116
119
|
ONTOLOGY_UPDATE_ENDPOINT: str = "ontology-update"
|
|
120
|
+
IMPORT_ENTITIES_ENDPOINT: str = "import"
|
|
121
|
+
IMPORT_ERROR_LOG_ENDPOINT: str = "import/errorlog"
|
|
117
122
|
|
|
118
123
|
def __init__(
|
|
119
124
|
self,
|
|
@@ -588,6 +593,222 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
|
|
|
588
593
|
await asyncio.sleep(0.25 if self.use_graceful_shutdown else 0.0)
|
|
589
594
|
return uri
|
|
590
595
|
|
|
596
|
+
async def import_entities(
|
|
597
|
+
self,
|
|
598
|
+
entities: List[ThingObject],
|
|
599
|
+
auth_key: Optional[str] = None,
|
|
600
|
+
timeout: int = DEFAULT_TIMEOUT
|
|
601
|
+
) -> str:
|
|
602
|
+
"""Import entities to the graph.
|
|
603
|
+
|
|
604
|
+
Parameters
|
|
605
|
+
----------
|
|
606
|
+
entities: List[ThingObject]
|
|
607
|
+
List of entities to import.
|
|
608
|
+
auth_key: Optional[str] = None
|
|
609
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
610
|
+
timeout: int
|
|
611
|
+
Timeout for the request (default: 60 seconds)
|
|
612
|
+
|
|
613
|
+
Returns
|
|
614
|
+
-------
|
|
615
|
+
job_id: str
|
|
616
|
+
ID of the job
|
|
617
|
+
|
|
618
|
+
Raises
|
|
619
|
+
------
|
|
620
|
+
WacomServiceException
|
|
621
|
+
If the graph service returns an error code.
|
|
622
|
+
"""
|
|
623
|
+
if auth_key is None:
|
|
624
|
+
auth_key, _ = await self.handle_token()
|
|
625
|
+
headers: dict = {USER_AGENT_HEADER_FLAG: self.user_agent, AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}"}
|
|
626
|
+
ndjson_lines: List[str] = []
|
|
627
|
+
for obj in entities:
|
|
628
|
+
data_dict = obj.__import_format_dict__()
|
|
629
|
+
ndjson_lines.append(json.dumps(data_dict)) # Convert each dict to a JSON string
|
|
630
|
+
|
|
631
|
+
ndjson_content = "\n".join(ndjson_lines) # Join JSON strings with newline
|
|
632
|
+
|
|
633
|
+
# Compress the NDJSON string to a gzip byte array
|
|
634
|
+
compressed_data: bytes = gzip.compress(ndjson_content.encode("utf-8"))
|
|
635
|
+
url: str = f"{self.service_base_url}{self.IMPORT_ENTITIES_ENDPOINT}"
|
|
636
|
+
data: aiohttp.FormData = aiohttp.FormData()
|
|
637
|
+
data.add_field("file", compressed_data, filename="import.njson.gz", content_type="application/x-gzip")
|
|
638
|
+
async with AsyncServiceAPIClient.__async_session__() as session:
|
|
639
|
+
async with session.post(
|
|
640
|
+
url, headers=headers, data=data, timeout=timeout, verify_ssl=self.verify_calls
|
|
641
|
+
) as response:
|
|
642
|
+
if response.ok:
|
|
643
|
+
structure: Dict[str, Any] = await response.json(loads=orjson.loads)
|
|
644
|
+
return structure["jobId"]
|
|
645
|
+
raise await handle_error("Import endpoint returns an error.", response)
|
|
646
|
+
|
|
647
|
+
async def import_entities_from_file(
|
|
648
|
+
self,
|
|
649
|
+
file_path: Path,
|
|
650
|
+
auth_key: Optional[str] = None,
|
|
651
|
+
timeout: int = DEFAULT_TIMEOUT
|
|
652
|
+
) -> str:
|
|
653
|
+
"""Import entities from a file to the graph.
|
|
654
|
+
|
|
655
|
+
Parameters
|
|
656
|
+
----------
|
|
657
|
+
file_path: Path
|
|
658
|
+
Path to the file containing entities in NDJSON format.
|
|
659
|
+
auth_key: Optional[str] = None
|
|
660
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
661
|
+
timeout: int
|
|
662
|
+
Timeout for the request (default: 60 seconds)
|
|
663
|
+
|
|
664
|
+
Returns
|
|
665
|
+
-------
|
|
666
|
+
job_id: str
|
|
667
|
+
ID of the job
|
|
668
|
+
|
|
669
|
+
Raises
|
|
670
|
+
------
|
|
671
|
+
WacomServiceException
|
|
672
|
+
If the graph service returns an error code.
|
|
673
|
+
"""
|
|
674
|
+
if not file_path.exists():
|
|
675
|
+
raise FileNotFoundError(f"The file {file_path} does not exist.")
|
|
676
|
+
if auth_key is None:
|
|
677
|
+
auth_key, _ = await self.handle_token()
|
|
678
|
+
headers: dict = {USER_AGENT_HEADER_FLAG: self.user_agent, AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}"}
|
|
679
|
+
with file_path.open("rb") as file:
|
|
680
|
+
# Compress the NDJSON string to a gzip byte array
|
|
681
|
+
compressed_data: bytes = file.read()
|
|
682
|
+
data: aiohttp.FormData = aiohttp.FormData()
|
|
683
|
+
data.add_field("file", compressed_data, filename="import.njson.gz",
|
|
684
|
+
content_type="application/x-gzip")
|
|
685
|
+
url: str = f"{self.service_base_url}{self.IMPORT_ENTITIES_ENDPOINT}"
|
|
686
|
+
async with AsyncServiceAPIClient.__async_session__() as session:
|
|
687
|
+
async with session.post(
|
|
688
|
+
url, headers=headers, data=data, timeout=timeout, verify_ssl=self.verify_calls
|
|
689
|
+
) as response:
|
|
690
|
+
if response.ok:
|
|
691
|
+
structure: Dict[str, Any] = await response.json(loads=orjson.loads)
|
|
692
|
+
return structure["jobId"]
|
|
693
|
+
raise await handle_error("Import endpoint returns an error.", response)
|
|
694
|
+
|
|
695
|
+
async def job_status(
|
|
696
|
+
self,
|
|
697
|
+
job_id: str,
|
|
698
|
+
auth_key: Optional[str] = None,
|
|
699
|
+
timeout: int = DEFAULT_TIMEOUT
|
|
700
|
+
) -> JobStatus:
|
|
701
|
+
"""
|
|
702
|
+
Retrieve the status of the job.
|
|
703
|
+
|
|
704
|
+
Parameters
|
|
705
|
+
----------
|
|
706
|
+
job_id: str
|
|
707
|
+
ID of the job
|
|
708
|
+
auth_key: Optional[str] = None
|
|
709
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
710
|
+
timeout: int
|
|
711
|
+
Timeout for the request (default: 60 seconds)
|
|
712
|
+
|
|
713
|
+
Returns
|
|
714
|
+
-------
|
|
715
|
+
job_status: JobStatus
|
|
716
|
+
Status of the job
|
|
717
|
+
"""
|
|
718
|
+
if auth_key is None:
|
|
719
|
+
auth_key, _ = await self.handle_token()
|
|
720
|
+
headers: dict = {USER_AGENT_HEADER_FLAG: self.user_agent, AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}"}
|
|
721
|
+
url: str = f"{self.service_base_url}{self.IMPORT_ENTITIES_ENDPOINT}/{job_id}"
|
|
722
|
+
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:
|
|
726
|
+
if response.ok:
|
|
727
|
+
structure: Dict[str, Any] = await response.json(loads=orjson.loads)
|
|
728
|
+
return JobStatus.from_dict(structure)
|
|
729
|
+
raise await handle_error(f"Retrieving job status for {job_id} failed.", response, headers=headers)
|
|
730
|
+
|
|
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
|
|
737
|
+
) -> ErrorLogResponse:
|
|
738
|
+
"""
|
|
739
|
+
Retrieve the error log of the job.
|
|
740
|
+
|
|
741
|
+
Parameters
|
|
742
|
+
----------
|
|
743
|
+
job_id: str
|
|
744
|
+
ID of the job
|
|
745
|
+
next_page_id: Optional[str] = None
|
|
746
|
+
ID of the next page within pagination.
|
|
747
|
+
auth_key: Optional[str] = None
|
|
748
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
749
|
+
timeout: int
|
|
750
|
+
Timeout for the request (default: 60 seconds)
|
|
751
|
+
|
|
752
|
+
Returns
|
|
753
|
+
-------
|
|
754
|
+
error: ErrorLogResponse
|
|
755
|
+
Error log of the job
|
|
756
|
+
"""
|
|
757
|
+
if auth_key is None:
|
|
758
|
+
auth_key, _ = await self.handle_token()
|
|
759
|
+
headers: dict = {USER_AGENT_HEADER_FLAG: self.user_agent, AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}"}
|
|
760
|
+
url: str = f"{self.service_base_url}{self.IMPORT_ERROR_LOG_ENDPOINT}/{job_id}"
|
|
761
|
+
params: Dict[str, str] = {NEXT_PAGE_ID_TAG: next_page_id} if next_page_id else {}
|
|
762
|
+
async with AsyncServiceAPIClient.__async_session__() as session:
|
|
763
|
+
async with session.get(
|
|
764
|
+
url, headers=headers, params=params, timeout=timeout, verify_ssl=self.verify_calls
|
|
765
|
+
) as response:
|
|
766
|
+
if response.ok:
|
|
767
|
+
structure: Dict[str, Any] = await response.json(loads=orjson.loads)
|
|
768
|
+
return ErrorLogResponse.from_dict(structure)
|
|
769
|
+
raise await handle_error(f"Retrieving job status for {job_id} failed.", response)
|
|
770
|
+
|
|
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
|
|
777
|
+
) -> NewEntityUrisResponse:
|
|
778
|
+
"""
|
|
779
|
+
Retrieve the new entity uris from the job.
|
|
780
|
+
|
|
781
|
+
Parameters
|
|
782
|
+
----------
|
|
783
|
+
job_id: str
|
|
784
|
+
ID of the job
|
|
785
|
+
next_page_id: Optional[str] = None
|
|
786
|
+
ID of the next page within pagination.
|
|
787
|
+
auth_key: Optional[str] = None
|
|
788
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
789
|
+
timeout: int
|
|
790
|
+
Timeout for the request (default: 60 seconds)
|
|
791
|
+
|
|
792
|
+
Returns
|
|
793
|
+
-------
|
|
794
|
+
response: NewEntityUrisResponse
|
|
795
|
+
New entity uris of the job.
|
|
796
|
+
"""
|
|
797
|
+
if auth_key is None:
|
|
798
|
+
auth_key, _ = await self.handle_token()
|
|
799
|
+
headers: dict = {USER_AGENT_HEADER_FLAG: self.user_agent, AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}"}
|
|
800
|
+
url: str = f"{self.service_base_url}{self.IMPORT_ENTITIES_ENDPOINT}/{job_id}/new-entities"
|
|
801
|
+
params: Dict[str, str] = {NEXT_PAGE_ID_TAG: next_page_id} if next_page_id else {}
|
|
802
|
+
async with AsyncServiceAPIClient.__async_session__() as session:
|
|
803
|
+
async with session.get(
|
|
804
|
+
url, headers=headers, params=params, timeout=timeout, verify_ssl=self.verify_calls
|
|
805
|
+
) as response:
|
|
806
|
+
if response.ok:
|
|
807
|
+
structure: Dict[str, Any] = await response.json(loads=orjson.loads)
|
|
808
|
+
return NewEntityUrisResponse.from_dict(structure)
|
|
809
|
+
raise await handle_error(f"Retrieving job status for {job_id} failed.", response)
|
|
810
|
+
|
|
811
|
+
|
|
591
812
|
async def update_entity(self, entity: ThingObject, auth_key: Optional[str] = None):
|
|
592
813
|
"""
|
|
593
814
|
Updates entity in graph.
|
|
@@ -1576,6 +1797,8 @@ class AsyncWacomKnowledgeService(AsyncServiceAPIClient):
|
|
|
1576
1797
|
content_link="",
|
|
1577
1798
|
ontology_types=entity_types,
|
|
1578
1799
|
entity_type=EntityType.PERSONAL_ENTITY,
|
|
1800
|
+
tokens=e.get("tokens"),
|
|
1801
|
+
token_indexes=e.get("tokenIndexes"),
|
|
1579
1802
|
)
|
|
1580
1803
|
ne.relevant_type = OntologyClassReference.parse(e["type"])
|
|
1581
1804
|
named_entities.append(ne)
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/graph.py
RENAMED
|
@@ -575,6 +575,8 @@ class WacomKnowledgeService(WacomServiceAPIClient):
|
|
|
575
575
|
if entity.image is not None and entity.image.startswith("file:"):
|
|
576
576
|
p = urlparse(entity.image)
|
|
577
577
|
self.set_entity_image_local(uri, Path(p.path), auth_key=auth_key)
|
|
578
|
+
elif entity.image is not None and entity.image.startswith("/"):
|
|
579
|
+
self.set_entity_image_local(uri, Path(entity.image), auth_key=auth_key)
|
|
578
580
|
elif entity.image is not None and entity.image != "":
|
|
579
581
|
self.set_entity_image_url(uri, entity.image, auth_key=auth_key)
|
|
580
582
|
except WacomServiceException as _:
|
|
@@ -1879,6 +1881,63 @@ class WacomKnowledgeService(WacomServiceAPIClient):
|
|
|
1879
1881
|
return response.json()["jobId"]
|
|
1880
1882
|
raise handle_error("Import endpoint returns an error.", response)
|
|
1881
1883
|
|
|
1884
|
+
def import_entities_from_file(
|
|
1885
|
+
self,
|
|
1886
|
+
file_path: Path,
|
|
1887
|
+
auth_key: Optional[str] = None,
|
|
1888
|
+
timeout: int = DEFAULT_TIMEOUT,
|
|
1889
|
+
max_retries: int = DEFAULT_MAX_RETRIES,
|
|
1890
|
+
backoff_factor: float = DEFAULT_BACKOFF_FACTOR,
|
|
1891
|
+
) -> str:
|
|
1892
|
+
"""Import entities from a file to the graph.
|
|
1893
|
+
|
|
1894
|
+
Parameters
|
|
1895
|
+
----------
|
|
1896
|
+
file_path: Path
|
|
1897
|
+
Path to the file containing entities in NDJSON format.
|
|
1898
|
+
auth_key: Optional[str] = None
|
|
1899
|
+
If the auth key is set the logged-in user (if any) will be ignored and the auth key will be used.
|
|
1900
|
+
timeout: int
|
|
1901
|
+
Timeout for the request (default: 60 seconds)
|
|
1902
|
+
max_retries: int
|
|
1903
|
+
Maximum number of retries
|
|
1904
|
+
backoff_factor: float
|
|
1905
|
+
A backoff factor to apply between attempts after the second try (most errors are resolved immediately by a
|
|
1906
|
+
second try without a delay)
|
|
1907
|
+
|
|
1908
|
+
Returns
|
|
1909
|
+
-------
|
|
1910
|
+
job_id: str
|
|
1911
|
+
ID of the job
|
|
1912
|
+
|
|
1913
|
+
Raises
|
|
1914
|
+
------
|
|
1915
|
+
WacomServiceException
|
|
1916
|
+
If the graph service returns an error code.
|
|
1917
|
+
"""
|
|
1918
|
+
if not file_path.exists():
|
|
1919
|
+
raise FileNotFoundError(f"The file {file_path} does not exist.")
|
|
1920
|
+
if auth_key is None:
|
|
1921
|
+
auth_key, _ = self.handle_token()
|
|
1922
|
+
headers: dict = {USER_AGENT_HEADER_FLAG: self.user_agent, AUTHORIZATION_HEADER_FLAG: f"Bearer {auth_key}"}
|
|
1923
|
+
with file_path.open("rb") as file:
|
|
1924
|
+
# Compress the NDJSON string to a gzip byte array
|
|
1925
|
+
compressed_data: bytes = file.read()
|
|
1926
|
+
files: List[Tuple[str, Tuple[str, bytes, str]]] = [
|
|
1927
|
+
("file", ("import.njson.gz", compressed_data, "application/x-gzip"))
|
|
1928
|
+
]
|
|
1929
|
+
url: str = f"{self.service_base_url}{self.IMPORT_ENTITIES_ENDPOINT}"
|
|
1930
|
+
mount_point: str = "https://" if self.service_url.startswith("https") else "http://"
|
|
1931
|
+
with requests.Session() as session:
|
|
1932
|
+
retries: Retry = Retry(total=max_retries, backoff_factor=backoff_factor, status_forcelist=STATUS_FORCE_LIST)
|
|
1933
|
+
session.mount(mount_point, HTTPAdapter(max_retries=retries))
|
|
1934
|
+
response: Response = session.post(
|
|
1935
|
+
url, headers=headers, files=files, timeout=timeout, verify=self.verify_calls
|
|
1936
|
+
)
|
|
1937
|
+
if response.ok:
|
|
1938
|
+
return response.json()["jobId"]
|
|
1939
|
+
raise handle_error("Import endpoint returns an error.", response)
|
|
1940
|
+
|
|
1882
1941
|
def job_status(
|
|
1883
1942
|
self,
|
|
1884
1943
|
job_id: str,
|
|
File without changes
|
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/base/__init__.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/base/access.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/base/entity.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/base/language.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/base/response.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/base/search.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/base/tenant.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/nel/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/public/__init__.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/public/cache.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/public/client.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/public/helper.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/public/relations.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/public/wikidata.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/base.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/group.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/helper.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/ontology.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/search.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/session.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/tenant.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/services/users.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/utils/__init__.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/utils/diff.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/utils/graph.py
RENAMED
|
File without changes
|
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/utils/wikidata.py
RENAMED
|
File without changes
|
{personal_knowledge_library-3.2.2 → personal_knowledge_library-3.3.1}/knowledge/utils/wikipedia.py
RENAMED
|
File without changes
|