personal_knowledge_library 3.1.1__py3-none-any.whl → 3.2.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 +1 -1
- knowledge/base/__init__.py +5 -1
- knowledge/base/language.py +2 -2
- knowledge/base/ontology.py +4 -2
- knowledge/base/response.py +361 -0
- knowledge/ontomapping/__init__.py +2 -0
- knowledge/public/client.py +3 -2
- knowledge/services/__init__.py +3 -1
- knowledge/services/asyncio/graph.py +116 -1
- knowledge/services/graph.py +226 -6
- knowledge/services/search.py +4 -4
- knowledge/services/tenant.py +2 -1
- knowledge/services/users.py +2 -0
- knowledge/utils/__init__.py +3 -3
- knowledge/utils/diff.py +598 -0
- knowledge/utils/import_format.py +168 -0
- {personal_knowledge_library-3.1.1.dist-info → personal_knowledge_library-3.2.0.dist-info}/METADATA +1 -1
- {personal_knowledge_library-3.1.1.dist-info → personal_knowledge_library-3.2.0.dist-info}/RECORD +20 -17
- {personal_knowledge_library-3.1.1.dist-info → personal_knowledge_library-3.2.0.dist-info}/WHEEL +1 -1
- {personal_knowledge_library-3.1.1.dist-info → personal_knowledge_library-3.2.0.dist-info}/LICENSE +0 -0
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright © 2024-present Wacom. All rights reserved.
|
|
3
|
+
import gzip
|
|
4
|
+
import json
|
|
5
|
+
import logging
|
|
6
|
+
import re
|
|
7
|
+
from json import JSONDecodeError
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import List, Dict, Any
|
|
10
|
+
|
|
11
|
+
import loguru
|
|
12
|
+
|
|
13
|
+
from knowledge.base.ontology import ThingObject, OntologyPropertyReference
|
|
14
|
+
|
|
15
|
+
logger = loguru.logger
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def is_http_url(url: str) -> bool:
|
|
19
|
+
"""Check if a string is an HTTP(S) URL.
|
|
20
|
+
Parameters
|
|
21
|
+
----------
|
|
22
|
+
url: str
|
|
23
|
+
The URL to check.
|
|
24
|
+
|
|
25
|
+
Returns
|
|
26
|
+
-------
|
|
27
|
+
bool
|
|
28
|
+
True if the URL is HTTP(S), False otherwise.
|
|
29
|
+
"""
|
|
30
|
+
return bool(re.match(r"^(https?://)", url, re.IGNORECASE))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def is_local_url(url: str) -> bool:
|
|
34
|
+
"""Check if a string is a local file path or relative URL.
|
|
35
|
+
Parameters
|
|
36
|
+
----------
|
|
37
|
+
url: str
|
|
38
|
+
The URL to check.
|
|
39
|
+
|
|
40
|
+
Returns
|
|
41
|
+
-------
|
|
42
|
+
bool
|
|
43
|
+
True if the URL is a local file path or relative URL, False otherwise.
|
|
44
|
+
"""
|
|
45
|
+
return bool(re.match(r"^(file://|/|\.{1,2}/)", url, re.IGNORECASE))
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def __import_format_to_thing__(line: str) -> ThingObject:
|
|
49
|
+
"""
|
|
50
|
+
Convert a line of JSON to a ThingObject.
|
|
51
|
+
Parameters
|
|
52
|
+
----------
|
|
53
|
+
line: str
|
|
54
|
+
The line of JSON to convert.
|
|
55
|
+
|
|
56
|
+
Returns
|
|
57
|
+
-------
|
|
58
|
+
entity: ThingObject
|
|
59
|
+
The ThingObject created from the JSON line.
|
|
60
|
+
|
|
61
|
+
Raises
|
|
62
|
+
------
|
|
63
|
+
JSONDecodeError
|
|
64
|
+
If the line is not valid JSON.
|
|
65
|
+
"""
|
|
66
|
+
thing_dict: Dict[str, Any] = json.loads(line)
|
|
67
|
+
entity: ThingObject = ThingObject.from_import_dict(thing_dict)
|
|
68
|
+
if entity.image:
|
|
69
|
+
if not is_local_url(entity.image) and not is_http_url(entity.image):
|
|
70
|
+
path: Path = Path(entity.image)
|
|
71
|
+
if not path.exists():
|
|
72
|
+
entity.image = path.absolute().as_uri()
|
|
73
|
+
else:
|
|
74
|
+
logger.warning(f"Image path {path} does not exist. Setting to None.")
|
|
75
|
+
entity.image = None
|
|
76
|
+
remove_props: List[OntologyPropertyReference] = []
|
|
77
|
+
# Remove empty properties
|
|
78
|
+
for obj_prop, value in entity.object_properties.items():
|
|
79
|
+
if len(value.incoming_relations) == 0 and len(value.outgoing_relations) == 0:
|
|
80
|
+
remove_props.append(obj_prop)
|
|
81
|
+
for prop in remove_props:
|
|
82
|
+
del entity.object_properties[prop]
|
|
83
|
+
return entity
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def load_import_format(file_path: Path) -> List[ThingObject]:
|
|
87
|
+
"""
|
|
88
|
+
Load the import format file.
|
|
89
|
+
Parameters
|
|
90
|
+
----------
|
|
91
|
+
file_path: Path
|
|
92
|
+
The path to the file.
|
|
93
|
+
|
|
94
|
+
Returns
|
|
95
|
+
-------
|
|
96
|
+
entity_list: List[ThingObject]
|
|
97
|
+
The list of entities.
|
|
98
|
+
|
|
99
|
+
Raises
|
|
100
|
+
------
|
|
101
|
+
FileNotFoundError
|
|
102
|
+
If the file does not exist or is not a file.
|
|
103
|
+
"""
|
|
104
|
+
if not file_path.exists():
|
|
105
|
+
logger.error(f"File {file_path} does not exist.")
|
|
106
|
+
raise FileNotFoundError(f"File {file_path} does not exist.")
|
|
107
|
+
if not file_path.is_file():
|
|
108
|
+
logger.error(f"Path {file_path} is not a file.")
|
|
109
|
+
raise FileNotFoundError(f"Path {file_path} is not a file.")
|
|
110
|
+
cached_entities: List[ThingObject] = []
|
|
111
|
+
if file_path.suffix == ".gz":
|
|
112
|
+
with gzip.open(file_path, "rt", encoding="utf-8") as f_gz:
|
|
113
|
+
for line_number, line in enumerate(f_gz):
|
|
114
|
+
stripped_line: str = line.strip()
|
|
115
|
+
if not stripped_line:
|
|
116
|
+
continue # Skip empty lines
|
|
117
|
+
if line_number == 0:
|
|
118
|
+
# Skip the first line (header)
|
|
119
|
+
continue
|
|
120
|
+
try:
|
|
121
|
+
cached_entities.append(__import_format_to_thing__(line))
|
|
122
|
+
except JSONDecodeError as e:
|
|
123
|
+
logging.error(f"Error decoding JSON: {e}. Line: {line}")
|
|
124
|
+
else:
|
|
125
|
+
with file_path.open(encoding="utf8") as f:
|
|
126
|
+
# Skip the first line
|
|
127
|
+
for line in f.readlines():
|
|
128
|
+
try:
|
|
129
|
+
cached_entities.append(__import_format_to_thing__(line))
|
|
130
|
+
except JSONDecodeError as e:
|
|
131
|
+
logging.error(f"Error decoding JSON: {e}. Line: {line}")
|
|
132
|
+
return cached_entities
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def save_import_format(file_path: Path, entities: List[ThingObject]) -> None:
|
|
136
|
+
"""
|
|
137
|
+
Save the import format file.
|
|
138
|
+
Parameters
|
|
139
|
+
----------
|
|
140
|
+
file_path: Path
|
|
141
|
+
The path to the file.
|
|
142
|
+
entities: List[ThingObject]
|
|
143
|
+
The list of entities.
|
|
144
|
+
"""
|
|
145
|
+
# Create the directory if it does not exist
|
|
146
|
+
file_path.parent.mkdir(parents=True, exist_ok=True)
|
|
147
|
+
if file_path.suffix == ".gz":
|
|
148
|
+
with gzip.open(file_path, "wt", encoding="utf-8") as fp_thing:
|
|
149
|
+
for entity in entities:
|
|
150
|
+
fp_thing.write(f"{json.dumps(entity.__import_format_dict__(), ensure_ascii=False)}\n")
|
|
151
|
+
elif file_path.suffix == ".ndjson":
|
|
152
|
+
with file_path.open("w", encoding="utf-8") as fp_thing:
|
|
153
|
+
for entity in entities:
|
|
154
|
+
fp_thing.write(f"{json.dumps(entity.__import_format_dict__(), ensure_ascii=False)}\n")
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def append_import_format(file_path: Path, entity: ThingObject) -> None:
|
|
158
|
+
"""
|
|
159
|
+
Append to the import format file.
|
|
160
|
+
Parameters
|
|
161
|
+
----------
|
|
162
|
+
file_path: Path
|
|
163
|
+
The path to the file.
|
|
164
|
+
entity: ThingObject
|
|
165
|
+
The entity to append.
|
|
166
|
+
"""
|
|
167
|
+
with file_path.open("a", encoding="utf-8") as fp_thing:
|
|
168
|
+
fp_thing.write(f"{json.dumps(entity.__import_format_dict__(), ensure_ascii=False)}\n")
|
{personal_knowledge_library-3.1.1.dist-info → personal_knowledge_library-3.2.0.dist-info}/RECORD
RENAMED
|
@@ -1,43 +1,46 @@
|
|
|
1
|
-
knowledge/__init__.py,sha256=
|
|
2
|
-
knowledge/base/__init__.py,sha256=
|
|
1
|
+
knowledge/__init__.py,sha256=xx1SZgmFpjbHD3ZgpA9Bdbh5YaadA-vu2Y6MPsu6rvY,2680
|
|
2
|
+
knowledge/base/__init__.py,sha256=rgAcl0azO6eoVk1gK9z0UFNlTHj3AN88k6LG-GdATFk,1079
|
|
3
3
|
knowledge/base/access.py,sha256=BSh-6QbeHOCu55XTxA-p3DwEyRzgtN8TSxtcn6UvmZo,4411
|
|
4
4
|
knowledge/base/entity.py,sha256=b-Ana_H_WI2-AT_n-V_HzUL6W9Ri16DcZFS3q4ziI94,8445
|
|
5
|
-
knowledge/base/language.py,sha256=
|
|
6
|
-
knowledge/base/ontology.py,sha256
|
|
5
|
+
knowledge/base/language.py,sha256=L4VAKRuFRQxE0BfzxkQUeChyhvLKoZM7ooqxm0dACO4,1478
|
|
6
|
+
knowledge/base/ontology.py,sha256=UMgJS2QVBskOiTFYbjNUxx1tY3jJZV-STF3UYf4ofKM,95435
|
|
7
|
+
knowledge/base/response.py,sha256=dqdskdcjKnM142nX_8sDVs8v7xTQjiVY1MqJCI-Dfkc,10918
|
|
7
8
|
knowledge/base/search.py,sha256=J1PSVpTU2JKF9xSZLZZvAbJfFy1HiMPJRzPjHhR7IQM,14722
|
|
8
9
|
knowledge/base/tenant.py,sha256=f2Z_LjUcjIt5J2_Rse9aQyTzJ0sSyVvCzlm8PP3PqY8,6084
|
|
9
10
|
knowledge/nel/__init__.py,sha256=eTT88LV_KQ-Ku-a4RnTv_TUCNogl357ui4KT1pEKMuQ,330
|
|
10
11
|
knowledge/nel/base.py,sha256=bsUj9PwoZoJWW33RfoYmQHbFhArKH1kMOsDgU3yj0T8,15032
|
|
11
12
|
knowledge/nel/engine.py,sha256=qvQkfsdeYPWJ_5m8mmGFw1tvd699vOQ3IKoBIwALRWk,5347
|
|
12
|
-
knowledge/ontomapping/__init__.py,sha256=
|
|
13
|
+
knowledge/ontomapping/__init__.py,sha256=u_t6i5a6pYYnf43Q_S6sG7NRLeGuKmahIHW6TFGHqOk,18848
|
|
13
14
|
knowledge/ontomapping/manager.py,sha256=pXBwRGSTcS731df5vewNv6oMgP18HzvnjZqiUgyFIhI,13361
|
|
14
15
|
knowledge/public/__init__.py,sha256=FrW5sqJGVcIfg5IVpt_g7qlWiIYNGA370jkE5mJDhoo,812
|
|
15
16
|
knowledge/public/cache.py,sha256=uKEuW9WN9xPmY-fwWPLSxmdEP6xg-XG3g8fKAmGZgBQ,14510
|
|
16
|
-
knowledge/public/client.py,sha256=
|
|
17
|
+
knowledge/public/client.py,sha256=7Z-nYhYIni_jKDWJw18CvuUxuOCns74l8XjeEEJXl_Y,15437
|
|
17
18
|
knowledge/public/helper.py,sha256=PDsInMHMHgP8rMvcFk5E47afdE3rC7V3BzPS-DdOsww,13238
|
|
18
19
|
knowledge/public/relations.py,sha256=DrL-rYuwLzaE2H2TOM2gG1TGqHbkcPL4EsRD54LQqLs,4182
|
|
19
20
|
knowledge/public/wikidata.py,sha256=LwMP2kq2mH5Oi9JhPvG8lN9pZMDlQvxgaZgQKQO3kaM,36683
|
|
20
|
-
knowledge/services/__init__.py,sha256=
|
|
21
|
+
knowledge/services/__init__.py,sha256=Pg4Pd9cCRiQ4-v3E0WCqldOhJFcMmkZrQHA7BY1Z1K8,3604
|
|
21
22
|
knowledge/services/asyncio/__init__.py,sha256=dq9yGTxg_hoQb8E1kEtY4AeB8zrdJfw3-XlPoYn2j5U,225
|
|
22
23
|
knowledge/services/asyncio/base.py,sha256=im6J1CWOp1N1tt6WdJ1uU0R-VFpvdYc6lZu8TyPrU5A,16222
|
|
23
|
-
knowledge/services/asyncio/graph.py,sha256=
|
|
24
|
+
knowledge/services/asyncio/graph.py,sha256=BRU8kLgKt7KNuyzlgT2PEVwa7ig-S-sR0AWMTYkp5NE,62401
|
|
24
25
|
knowledge/services/asyncio/group.py,sha256=UKbk8vnPqqAkuc5gAd6g3IVOKmUJNqG2lreZM0O-hRg,18356
|
|
25
26
|
knowledge/services/asyncio/search.py,sha256=_ESVbNGLYbo7EmyMLtsh0pRiRHIyGeBicrcD2JKbFwY,16215
|
|
26
27
|
knowledge/services/asyncio/users.py,sha256=NJ7xagjr4gF6yKJXdwa0bz0eaYlQDee5RCEpfQJEHWk,10274
|
|
27
28
|
knowledge/services/base.py,sha256=gXBIkbk7wXGrm_hZGfLvft7-E8fcSMjl-HIsLxfRZ6c,17849
|
|
28
|
-
knowledge/services/graph.py,sha256=
|
|
29
|
+
knowledge/services/graph.py,sha256=XhbB2-3CUkQ9-NdVoW9pcQfnItaX6H07WVTsK3ynZ5I,86888
|
|
29
30
|
knowledge/services/group.py,sha256=b8dBBrHXqgwpJ7BtUqqweoR_WQH5MZ0aLh0fBBTyHUI,30698
|
|
30
31
|
knowledge/services/helper.py,sha256=NYhRkYXtiFgovsXaQr6rBVN2mjBwOT7cSSuLTyjvzKA,4990
|
|
31
32
|
knowledge/services/ontology.py,sha256=u89S3GV0C2FWAviQxd5fvoCQWzo8EhYix7fQc1bEEc0,51534
|
|
32
|
-
knowledge/services/search.py,sha256
|
|
33
|
+
knowledge/services/search.py,sha256=-qB9J1pyqoq3RlH7iDlgozBImKFzTx1p1kC0XKWAPEs,19147
|
|
33
34
|
knowledge/services/session.py,sha256=y8uTETRMDOBbC30UAlrrtWTN7Zgs2klqHsoMjLO2tq0,14145
|
|
34
|
-
knowledge/services/tenant.py,sha256=
|
|
35
|
-
knowledge/services/users.py,sha256=
|
|
36
|
-
knowledge/utils/__init__.py,sha256=
|
|
35
|
+
knowledge/services/tenant.py,sha256=rQsUe8qNFTt_WZG4XBTg8QSLoyavuCWLWk3QhU1fBG8,11728
|
|
36
|
+
knowledge/services/users.py,sha256=nOwyZhqERTNFPTN21c_q7-6XaEMb3SnHfnXr4Kf22qk,16594
|
|
37
|
+
knowledge/utils/__init__.py,sha256=7unsBV5ge6eIyicKCIc_C4OroD-zkKRMVE0jXcH6EOw,313
|
|
38
|
+
knowledge/utils/diff.py,sha256=HrU03qGvkirPqC0vRRZRLA49eI08o-JI3dcHS5-uv4g,26647
|
|
37
39
|
knowledge/utils/graph.py,sha256=kuPZEGhexVN9McoT8JK2ViIrfXTh-nFPv_8XPfG0wlA,12318
|
|
40
|
+
knowledge/utils/import_format.py,sha256=fjuWpd91eAs7MbqSpLrFgdRvFaHK0nzV1L83ByjTmV0,5277
|
|
38
41
|
knowledge/utils/wikidata.py,sha256=vRH-4AMR-3xywyvmDqbjI4KSw4tF4TEYqUGCJmUMqK8,5512
|
|
39
42
|
knowledge/utils/wikipedia.py,sha256=rBuFqYVM58JCj5ISLxuhYVVl2gOIlPLWx7_CghyQgvE,5052
|
|
40
|
-
personal_knowledge_library-3.
|
|
41
|
-
personal_knowledge_library-3.
|
|
42
|
-
personal_knowledge_library-3.
|
|
43
|
-
personal_knowledge_library-3.
|
|
43
|
+
personal_knowledge_library-3.2.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
44
|
+
personal_knowledge_library-3.2.0.dist-info/METADATA,sha256=4RhzFCxjAyhFmnRavgdpwY5x-9PWs9p08tEqd9j1f6U,57087
|
|
45
|
+
personal_knowledge_library-3.2.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
46
|
+
personal_knowledge_library-3.2.0.dist-info/RECORD,,
|
{personal_knowledge_library-3.1.1.dist-info → personal_knowledge_library-3.2.0.dist-info}/LICENSE
RENAMED
|
File without changes
|