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
knowledge/__init__.py
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright © 2021-present Wacom. All rights reserved.
|
|
3
|
+
"""
|
|
4
|
+
Personal knowledge Library
|
|
5
|
+
--------------------------
|
|
6
|
+
This library provides a set of tools to manage Wacom private knowledge graph API.
|
|
7
|
+
All services are wrapped in a pythonic way to make it easy to use.
|
|
8
|
+
Additionally, the library provides a set of tools to utilise Wikidata.
|
|
9
|
+
"""
|
|
10
|
+
import sys
|
|
11
|
+
from datetime import datetime
|
|
12
|
+
|
|
13
|
+
__author__ = "Markus Weber"
|
|
14
|
+
__copyright__ = "Copyright 2021-present Wacom. All rights reserved."
|
|
15
|
+
__credits__ = ["Markus Weber"]
|
|
16
|
+
__license__ = "Wacom"
|
|
17
|
+
__maintainer__ = ["Markus Weber"]
|
|
18
|
+
__email__ = "markus.weber@wacom.com"
|
|
19
|
+
__status__ = "beta"
|
|
20
|
+
__version__ = "3.0.0"
|
|
21
|
+
|
|
22
|
+
import loguru
|
|
23
|
+
|
|
24
|
+
# Create the Logger
|
|
25
|
+
logger = None
|
|
26
|
+
|
|
27
|
+
if logger is None:
|
|
28
|
+
import logging
|
|
29
|
+
import inspect
|
|
30
|
+
from typing import Union
|
|
31
|
+
|
|
32
|
+
class InterceptHandler(logging.Handler):
|
|
33
|
+
"""
|
|
34
|
+
Custom logging handler to redirect logs from the standard logging module to Loguru.
|
|
35
|
+
This handler intercepts log messages and forwards them to the Loguru logger.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
def emit(self, record: logging.LogRecord) -> None:
|
|
39
|
+
# Get corresponding Loguru level if it exists.
|
|
40
|
+
try:
|
|
41
|
+
level: Union[str, int] = logger.level(record.levelname).name
|
|
42
|
+
except ValueError:
|
|
43
|
+
level = record.levelno
|
|
44
|
+
|
|
45
|
+
# Find caller from where originated the logged message.
|
|
46
|
+
frame, depth = inspect.currentframe(), 0
|
|
47
|
+
while frame:
|
|
48
|
+
filename = frame.f_code.co_filename
|
|
49
|
+
is_logging = filename == logging.__file__
|
|
50
|
+
is_frozen = "importlib" in filename and "_bootstrap" in filename
|
|
51
|
+
if depth > 0 and not (is_logging or is_frozen):
|
|
52
|
+
break
|
|
53
|
+
frame = frame.f_back
|
|
54
|
+
depth += 1
|
|
55
|
+
|
|
56
|
+
logger.opt(depth=depth, exception=record.exc_info).log(level, record.getMessage())
|
|
57
|
+
|
|
58
|
+
logger = loguru.logger
|
|
59
|
+
logger.remove()
|
|
60
|
+
logger.info("Logger initialized in for pks tools.")
|
|
61
|
+
today = datetime.now()
|
|
62
|
+
logger.add(
|
|
63
|
+
sys.stderr,
|
|
64
|
+
colorize=True,
|
|
65
|
+
format="{time:YYYY-MM-DD at HH:mm:ss} | {level} | {message}",
|
|
66
|
+
level="INFO",
|
|
67
|
+
enqueue=True,
|
|
68
|
+
)
|
|
69
|
+
logging.basicConfig(handlers=[InterceptHandler()], level=0, force=True)
|
|
70
|
+
|
|
71
|
+
__all__ = [
|
|
72
|
+
"__copyright__",
|
|
73
|
+
"__credits__",
|
|
74
|
+
"__license__",
|
|
75
|
+
"__maintainer__",
|
|
76
|
+
"__email__",
|
|
77
|
+
"__status__",
|
|
78
|
+
"__version__",
|
|
79
|
+
"logger",
|
|
80
|
+
"base",
|
|
81
|
+
"nel",
|
|
82
|
+
"public",
|
|
83
|
+
"services",
|
|
84
|
+
"utils",
|
|
85
|
+
]
|
|
86
|
+
|
|
87
|
+
from knowledge import base
|
|
88
|
+
from knowledge import nel
|
|
89
|
+
from knowledge import public
|
|
90
|
+
from knowledge import services
|
|
91
|
+
from knowledge import utils
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright © 2021-present Wacom. All rights reserved.
|
|
3
|
+
"""
|
|
4
|
+
Base structures.
|
|
5
|
+
----------------
|
|
6
|
+
This module provides the base structures for the knowledge graph.
|
|
7
|
+
Such as the ontology, entities and access.
|
|
8
|
+
|
|
9
|
+
The classes in this module are used by the knowledge graph service.
|
|
10
|
+
For instance, the ontology structure is used to create the structure knowledge graph.
|
|
11
|
+
The entities are used to store the knowledge graph.
|
|
12
|
+
|
|
13
|
+
The access is used to access the knowledge graph, there are different types of access:
|
|
14
|
+
- Private access: the user can access only the entities that he/she created.
|
|
15
|
+
- Public access: the user can access all the entities.
|
|
16
|
+
- Group access: the user can access the entities that are in the same group.
|
|
17
|
+
"""
|
|
18
|
+
__all__ = ["access", "entity", "ontology"]
|
|
19
|
+
|
|
20
|
+
from knowledge.base import access
|
|
21
|
+
from knowledge.base import entity
|
|
22
|
+
from knowledge.base import ontology
|
knowledge/base/access.py
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright © 2021-present Wacom. All rights reserved.
|
|
3
|
+
from typing import List
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class AccessRight:
|
|
7
|
+
"""
|
|
8
|
+
Access rights for entities within a tenant.
|
|
9
|
+
|
|
10
|
+
Parameters
|
|
11
|
+
----------
|
|
12
|
+
read: bool (default := False)
|
|
13
|
+
Read access for entity within tenant.
|
|
14
|
+
write: bool (default := False)
|
|
15
|
+
Write access for entity within tenant.
|
|
16
|
+
delete: bool (default := False)
|
|
17
|
+
Delete access for entity within tenant.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
READ: str = "Read"
|
|
21
|
+
WRITE: str = "Write"
|
|
22
|
+
DELETE: str = "Delete"
|
|
23
|
+
|
|
24
|
+
def __init__(self, read: bool, write: bool, delete: bool):
|
|
25
|
+
self.__read: bool = read
|
|
26
|
+
self.__write: bool = write
|
|
27
|
+
self.__delete: bool = delete
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def read(self) -> bool:
|
|
31
|
+
"""Read access for tenant."""
|
|
32
|
+
return self.__read
|
|
33
|
+
|
|
34
|
+
@read.setter
|
|
35
|
+
def read(self, value: bool):
|
|
36
|
+
self.__read = value
|
|
37
|
+
|
|
38
|
+
@property
|
|
39
|
+
def write(self) -> bool:
|
|
40
|
+
"""Write access for tenant."""
|
|
41
|
+
return self.__write
|
|
42
|
+
|
|
43
|
+
@write.setter
|
|
44
|
+
def write(self, value: bool):
|
|
45
|
+
self.__write = value
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def delete(self) -> bool:
|
|
49
|
+
"""Delete access for tenant."""
|
|
50
|
+
return self.__delete
|
|
51
|
+
|
|
52
|
+
@delete.setter
|
|
53
|
+
def delete(self, value: bool):
|
|
54
|
+
self.__delete = value
|
|
55
|
+
|
|
56
|
+
def __repr__(self):
|
|
57
|
+
result: str = "["
|
|
58
|
+
prefix: str = ""
|
|
59
|
+
if self.read:
|
|
60
|
+
result += AccessRight.READ
|
|
61
|
+
prefix = ", "
|
|
62
|
+
if self.write:
|
|
63
|
+
result += prefix + AccessRight.WRITE
|
|
64
|
+
if self.delete:
|
|
65
|
+
result += AccessRight.DELETE
|
|
66
|
+
result += "]"
|
|
67
|
+
return result
|
|
68
|
+
|
|
69
|
+
def to_list(self) -> List[str]:
|
|
70
|
+
"""
|
|
71
|
+
Converts the access to list of properties.
|
|
72
|
+
|
|
73
|
+
Returns
|
|
74
|
+
-------
|
|
75
|
+
access_list: List[str]
|
|
76
|
+
List of rights
|
|
77
|
+
"""
|
|
78
|
+
rights: List[str] = []
|
|
79
|
+
if self.read:
|
|
80
|
+
rights.append(TenantAccessRight.READ)
|
|
81
|
+
if self.write:
|
|
82
|
+
rights.append(TenantAccessRight.WRITE)
|
|
83
|
+
if self.delete:
|
|
84
|
+
rights.append(TenantAccessRight.DELETE)
|
|
85
|
+
return rights
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
class TenantAccessRight(AccessRight):
|
|
89
|
+
"""
|
|
90
|
+
TenantAccessRight
|
|
91
|
+
-----------------
|
|
92
|
+
Access rights for entities within a tenant.
|
|
93
|
+
|
|
94
|
+
Parameters
|
|
95
|
+
----------
|
|
96
|
+
read: bool (default := False)
|
|
97
|
+
Read access for entity within tenant.
|
|
98
|
+
write: bool (default := False)
|
|
99
|
+
Write access for entity within tenant.
|
|
100
|
+
delete: bool (default := False)
|
|
101
|
+
Delete access for entity within tenant.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
def __init__(self, read: bool = False, write: bool = False, delete: bool = False):
|
|
105
|
+
super().__init__(read, write, delete)
|
|
106
|
+
|
|
107
|
+
@classmethod
|
|
108
|
+
def parse(cls, param: List[str]) -> "TenantAccessRight":
|
|
109
|
+
"""
|
|
110
|
+
Converts the access to list of properties.
|
|
111
|
+
|
|
112
|
+
Parameters
|
|
113
|
+
----------
|
|
114
|
+
param: List[str]
|
|
115
|
+
List of rights
|
|
116
|
+
|
|
117
|
+
Returns
|
|
118
|
+
-------
|
|
119
|
+
tenant_rights: TenantAccessRight
|
|
120
|
+
Instantiated rights.
|
|
121
|
+
"""
|
|
122
|
+
rights: TenantAccessRight = TenantAccessRight()
|
|
123
|
+
rights.read = TenantAccessRight.READ in param
|
|
124
|
+
rights.write = TenantAccessRight.WRITE in param
|
|
125
|
+
rights.delete = TenantAccessRight.DELETE in param
|
|
126
|
+
return rights
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class GroupAccessRight(AccessRight):
|
|
130
|
+
"""
|
|
131
|
+
GroupAccessRight
|
|
132
|
+
-----------------
|
|
133
|
+
Group rights for entities within a group.
|
|
134
|
+
|
|
135
|
+
Parameters
|
|
136
|
+
----------
|
|
137
|
+
read: bool (default := False)
|
|
138
|
+
Read access for entity within group.
|
|
139
|
+
write: bool (default := False)
|
|
140
|
+
Write access for entity within group.
|
|
141
|
+
delete: bool (default := False)
|
|
142
|
+
Delete access for entity within group.
|
|
143
|
+
"""
|
|
144
|
+
|
|
145
|
+
def __init__(self, read: bool = False, write: bool = False, delete: bool = False):
|
|
146
|
+
super().__init__(read, write, delete)
|
|
147
|
+
|
|
148
|
+
@classmethod
|
|
149
|
+
def parse(cls, param: List[str]) -> "GroupAccessRight":
|
|
150
|
+
"""
|
|
151
|
+
Converts the access to list of properties.
|
|
152
|
+
|
|
153
|
+
Parameters
|
|
154
|
+
----------
|
|
155
|
+
param: List[str]
|
|
156
|
+
List of rights
|
|
157
|
+
|
|
158
|
+
Returns
|
|
159
|
+
-------
|
|
160
|
+
group_rights: GroupAccessRight
|
|
161
|
+
Instantiated rights.
|
|
162
|
+
"""
|
|
163
|
+
rights: GroupAccessRight = GroupAccessRight()
|
|
164
|
+
rights.read = GroupAccessRight.READ in param
|
|
165
|
+
rights.write = GroupAccessRight.WRITE in param
|
|
166
|
+
rights.delete = GroupAccessRight.DELETE in param
|
|
167
|
+
return rights
|
knowledge/base/entity.py
ADDED
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright © 2021-present Wacom. All rights reserved.
|
|
3
|
+
import abc
|
|
4
|
+
import enum
|
|
5
|
+
from typing import Any, List, Dict, Union
|
|
6
|
+
|
|
7
|
+
from knowledge.base.language import LocaleCode, LanguageCode, EN_US
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
# ---------------------------------------- Exceptions -----------------------------------------------------------------
|
|
11
|
+
class ServiceException(Exception):
|
|
12
|
+
"""Service exception."""
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class KnowledgeException(Exception):
|
|
16
|
+
"""Knowledge exception."""
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# ---------------------------------------- Constants ------------------------------------------------------------------
|
|
20
|
+
RDF_SYNTAX_NS_TYPE: str = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
|
|
21
|
+
RDF_SCHEMA_COMMENT: str = "http://www.w3.org/2000/01/rdf-schema#comment"
|
|
22
|
+
RDF_SCHEMA_LABEL: str = "http://www.w3.org/2000/01/rdf-schema#label"
|
|
23
|
+
ALIAS_TAG: str = "alias"
|
|
24
|
+
DATA_PROPERTY_TAG: str = "literal"
|
|
25
|
+
VALUE_TAG: str = "value"
|
|
26
|
+
LANGUAGE_TAG: str = "lang"
|
|
27
|
+
LOCALE_TAG: str = "locale"
|
|
28
|
+
DATA_PROPERTIES_TAG: str = "literals"
|
|
29
|
+
SEND_TO_NEL_TAG: str = "sendToNEL"
|
|
30
|
+
SEND_VECTOR_INDEX_TAG: str = "sendToVectorIndex"
|
|
31
|
+
SOURCE_REFERENCE_ID_TAG: str = "source_reference_id"
|
|
32
|
+
EXTERNAL_USER_ID_TAG: str = "external_user_id"
|
|
33
|
+
SOURCE_SYSTEM_TAG: str = "source_system"
|
|
34
|
+
OBJECT_PROPERTIES_TAG: str = "relations"
|
|
35
|
+
OWNER_TAG: str = "owner"
|
|
36
|
+
OWNER_ID_TAG: str = "ownerId"
|
|
37
|
+
GROUP_IDS: str = "groupIds"
|
|
38
|
+
LOCALIZED_CONTENT_TAG: str = "LocalizedContent"
|
|
39
|
+
STATUS_FLAG_TAG: str = "status"
|
|
40
|
+
CONTENT_TAG: str = "value"
|
|
41
|
+
URI_TAG: str = "uri"
|
|
42
|
+
URIS_TAG: str = "uris"
|
|
43
|
+
FORCE_TAG: str = "force"
|
|
44
|
+
ERRORS_TAG: str = "errors"
|
|
45
|
+
TEXT_TAG: str = "text"
|
|
46
|
+
TYPE_TAG: str = "type"
|
|
47
|
+
IMAGE_TAG: str = "image"
|
|
48
|
+
DESCRIPTION_TAG: str = "description"
|
|
49
|
+
COMMENT_TAG: str = "text"
|
|
50
|
+
COMMENTS_TAG: str = "comments"
|
|
51
|
+
DESCRIPTIONS_TAG: str = "descriptions"
|
|
52
|
+
REPOSITORY_TAG: str = "repository"
|
|
53
|
+
DISPLAY_TAG: str = "display"
|
|
54
|
+
USE_NEL_TAG: str = "use_for_nel"
|
|
55
|
+
USE_VECTOR_INDEX_TAG: str = "use_for_vector_index"
|
|
56
|
+
USE_VECTOR_DOCUMENT_INDEX_TAG: str = "use_for_vector_document_index"
|
|
57
|
+
USE_FULLTEXT_TAG: str = "user_full_text"
|
|
58
|
+
TARGETS_TAG: str = "targets"
|
|
59
|
+
VISIBILITY_TAG: str = "visibility"
|
|
60
|
+
RELATIONS_TAG: str = "relations"
|
|
61
|
+
LABELS_TAG: str = "labels"
|
|
62
|
+
IS_MAIN_TAG: str = "isMain"
|
|
63
|
+
DATA_TYPE_TAG: str = "dataType"
|
|
64
|
+
RELATION_TAG: str = "relation"
|
|
65
|
+
OUTGOING_TAG: str = "out"
|
|
66
|
+
INCOMING_TAG: str = "in"
|
|
67
|
+
TENANT_RIGHTS_TAG: str = "tenantRights"
|
|
68
|
+
INFLECTION_CONCEPT_CLASS: str = "concept"
|
|
69
|
+
INFLECTION_SETTING: str = "inflection"
|
|
70
|
+
INFLECTION_CASE_SENSITIVE: str = "caseSensitive"
|
|
71
|
+
# ------------------------------------------ Indexing targets ----------------------------------------------------------
|
|
72
|
+
INDEXING_NEL_TARGET: str = "NEL"
|
|
73
|
+
INDEXING_VECTOR_SEARCH_TARGET: str = "VectorSearchWord"
|
|
74
|
+
INDEXING_VECTOR_SEARCH_DOCUMENT_TARGET: str = "VectorSearchDocument"
|
|
75
|
+
INDEXING_FULLTEXT_TARGET: str = "ElasticSearch"
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class EntityStatus(enum.Enum):
|
|
79
|
+
"""
|
|
80
|
+
Entity Status
|
|
81
|
+
-------------
|
|
82
|
+
Status of the entity synchronization (client and knowledge graph).
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
UNKNOWN = 0
|
|
86
|
+
"""Unknown status."""
|
|
87
|
+
CREATED = 1
|
|
88
|
+
"""Entity has been created and not yet update."""
|
|
89
|
+
UPDATED = 2
|
|
90
|
+
"""Entity has been updated by the client and must be synced."""
|
|
91
|
+
SYNCED = 3
|
|
92
|
+
"""State of entity is in sync with knowledge graph."""
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
class LocalizedContent(abc.ABC):
|
|
96
|
+
"""
|
|
97
|
+
Localized content
|
|
98
|
+
-----------------
|
|
99
|
+
Content that is multilingual.
|
|
100
|
+
|
|
101
|
+
Parameters
|
|
102
|
+
----------
|
|
103
|
+
content: str
|
|
104
|
+
Content value
|
|
105
|
+
language_code: LanguageCode (default:= 'en_US')
|
|
106
|
+
ISO-3166 Country Codes and ISO-639 Language Codes in the format '<language_code>_<country>', e.g., 'en_US'.
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
def __init__(self, content: str, language_code: Union[LocaleCode, LanguageCode]):
|
|
110
|
+
self.__content: str = content
|
|
111
|
+
self.__language_code: Union[LocaleCode, LanguageCode] = language_code
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
def content(self) -> str:
|
|
115
|
+
"""String representation of the content."""
|
|
116
|
+
return self.__content
|
|
117
|
+
|
|
118
|
+
@content.setter
|
|
119
|
+
def content(self, value: str):
|
|
120
|
+
self.__content = value
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
def language_code(self) -> Union[LocaleCode, LanguageCode]:
|
|
124
|
+
"""Locale"""
|
|
125
|
+
return self.__language_code
|
|
126
|
+
|
|
127
|
+
def __repr__(self):
|
|
128
|
+
return f"{self.content}@{self.language_code}"
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class Label(LocalizedContent):
|
|
132
|
+
"""
|
|
133
|
+
Label
|
|
134
|
+
-----
|
|
135
|
+
Label that is multilingual.
|
|
136
|
+
|
|
137
|
+
Parameters
|
|
138
|
+
----------
|
|
139
|
+
content: str
|
|
140
|
+
Content value
|
|
141
|
+
language_code: LocaleCode (default:= 'en_US')
|
|
142
|
+
ISO-3166 Country Codes and ISO-639 Language Codes in the format <language_code>_<country>, e.g., en_US.
|
|
143
|
+
main: bool (default:=False)
|
|
144
|
+
Main content
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
def __init__(self, content: str, language_code: LocaleCode = EN_US, main: bool = False):
|
|
148
|
+
self.__main: bool = main
|
|
149
|
+
super().__init__(content, language_code)
|
|
150
|
+
|
|
151
|
+
@property
|
|
152
|
+
def main(self) -> bool:
|
|
153
|
+
"""Flag if the content is the main content or an alias."""
|
|
154
|
+
return self.__main
|
|
155
|
+
|
|
156
|
+
@staticmethod
|
|
157
|
+
def create_from_dict(
|
|
158
|
+
dict_label: Dict[str, Any], tag_name: str = CONTENT_TAG, locale_name: str = LOCALE_TAG
|
|
159
|
+
) -> "Label":
|
|
160
|
+
"""
|
|
161
|
+
Create a label from a dictionary.
|
|
162
|
+
Parameters
|
|
163
|
+
----------
|
|
164
|
+
dict_label: Dict[str, Any]
|
|
165
|
+
Dictionary containing the label information.
|
|
166
|
+
tag_name: str
|
|
167
|
+
Tag name of the content.
|
|
168
|
+
locale_name: str
|
|
169
|
+
Tag name of the language code.
|
|
170
|
+
|
|
171
|
+
Returns
|
|
172
|
+
-------
|
|
173
|
+
instance: Label
|
|
174
|
+
The Label instance.
|
|
175
|
+
"""
|
|
176
|
+
if tag_name not in dict_label:
|
|
177
|
+
raise ValueError("Dict is does not contain a localized label.")
|
|
178
|
+
if locale_name not in dict_label:
|
|
179
|
+
raise ValueError("Dict is does not contain a language code")
|
|
180
|
+
if IS_MAIN_TAG in dict_label:
|
|
181
|
+
return Label(dict_label[tag_name], LocaleCode(dict_label[locale_name]), dict_label[IS_MAIN_TAG])
|
|
182
|
+
return Label(dict_label[tag_name], LocaleCode(dict_label[locale_name]))
|
|
183
|
+
|
|
184
|
+
@staticmethod
|
|
185
|
+
def create_from_list(param: List[dict]) -> List[LOCALIZED_CONTENT_TAG]:
|
|
186
|
+
"""
|
|
187
|
+
Create a list of labels from a list of dictionaries.
|
|
188
|
+
|
|
189
|
+
Parameters
|
|
190
|
+
----------
|
|
191
|
+
param: List[dict]
|
|
192
|
+
List of dictionaries containing the label information.
|
|
193
|
+
|
|
194
|
+
Returns
|
|
195
|
+
-------
|
|
196
|
+
instance: List[Label]
|
|
197
|
+
List of label instances.
|
|
198
|
+
"""
|
|
199
|
+
return [Label.create_from_dict(p) for p in param]
|
|
200
|
+
|
|
201
|
+
def __dict__(self):
|
|
202
|
+
return {CONTENT_TAG: self.content, LOCALE_TAG: self.language_code, IS_MAIN_TAG: self.main}
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
class Description(LocalizedContent):
|
|
206
|
+
"""
|
|
207
|
+
Description
|
|
208
|
+
-----------
|
|
209
|
+
Description that is multilingual.
|
|
210
|
+
|
|
211
|
+
Parameters
|
|
212
|
+
----------
|
|
213
|
+
description: str
|
|
214
|
+
Description value
|
|
215
|
+
language_code: LanguageCode (default:= 'en_US')
|
|
216
|
+
Language code of content
|
|
217
|
+
"""
|
|
218
|
+
|
|
219
|
+
def __init__(self, description: str, language_code: LocaleCode = EN_US):
|
|
220
|
+
super().__init__(description, language_code)
|
|
221
|
+
|
|
222
|
+
@staticmethod
|
|
223
|
+
def create_from_dict(
|
|
224
|
+
dict_description: Dict[str, Any], tag_name: str = DESCRIPTION_TAG, locale_name: str = LOCALE_TAG
|
|
225
|
+
) -> "Description":
|
|
226
|
+
"""
|
|
227
|
+
Create a description from a dictionary.
|
|
228
|
+
|
|
229
|
+
Parameters
|
|
230
|
+
----------
|
|
231
|
+
dict_description: Dict[str, Any]
|
|
232
|
+
Dictionary containing the description information.
|
|
233
|
+
tag_name: str
|
|
234
|
+
Tag name of the content.
|
|
235
|
+
locale_name:
|
|
236
|
+
Tag name of the language code.
|
|
237
|
+
|
|
238
|
+
Returns
|
|
239
|
+
-------
|
|
240
|
+
instance: Description
|
|
241
|
+
The description instance.
|
|
242
|
+
"""
|
|
243
|
+
if tag_name not in dict_description or locale_name not in dict_description:
|
|
244
|
+
raise ValueError("Dict is does not contain a localized label.")
|
|
245
|
+
return Description(dict_description[tag_name], LocaleCode(dict_description[locale_name]))
|
|
246
|
+
|
|
247
|
+
@staticmethod
|
|
248
|
+
def create_from_list(param: List[Dict[str, Any]]) -> List["Description"]:
|
|
249
|
+
"""Create a list of descriptions from a list of dictionaries.
|
|
250
|
+
|
|
251
|
+
Parameters
|
|
252
|
+
----------
|
|
253
|
+
param: List[Dict[str, Any]]
|
|
254
|
+
List of dictionaries containing the description information.
|
|
255
|
+
|
|
256
|
+
Returns
|
|
257
|
+
-------
|
|
258
|
+
instance: List[Description]
|
|
259
|
+
List of description instances.
|
|
260
|
+
"""
|
|
261
|
+
return [Description.create_from_dict(p) for p in param]
|
|
262
|
+
|
|
263
|
+
def __dict__(self):
|
|
264
|
+
return {
|
|
265
|
+
DESCRIPTION_TAG: self.content,
|
|
266
|
+
LOCALE_TAG: self.language_code,
|
|
267
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright © 2024-present Wacom. All rights reserved.
|
|
3
|
+
from typing import NewType, List, Dict
|
|
4
|
+
|
|
5
|
+
# ---------------------------------------- Type definitions -----------------------------------------------------------
|
|
6
|
+
LanguageCode = NewType("LanguageCode", str)
|
|
7
|
+
LocaleCode = NewType("LocaleCode", str)
|
|
8
|
+
# ------------------------------------------------ Language codes ------------------------------------------------------
|
|
9
|
+
EN_US: LocaleCode = LocaleCode("en_US")
|
|
10
|
+
JA_JP: LocaleCode = LocaleCode("ja_JP")
|
|
11
|
+
DE_DE: LocaleCode = LocaleCode("de_DE")
|
|
12
|
+
BG_BG: LocaleCode = LocaleCode("bg_BG")
|
|
13
|
+
FR_FR: LocaleCode = LocaleCode("fr_FR")
|
|
14
|
+
IT_IT: LocaleCode = LocaleCode("it_IT")
|
|
15
|
+
ES_ES: LocaleCode = LocaleCode("es_ES")
|
|
16
|
+
EN: LanguageCode = LanguageCode("en")
|
|
17
|
+
DE: LanguageCode = LanguageCode("de")
|
|
18
|
+
BG: LanguageCode = LanguageCode("bg")
|
|
19
|
+
JA: LanguageCode = LanguageCode("ja")
|
|
20
|
+
FR: LanguageCode = LanguageCode("fr")
|
|
21
|
+
IT: LanguageCode = LanguageCode("it")
|
|
22
|
+
ES: LanguageCode = LanguageCode("es")
|
|
23
|
+
# ----------------------------------------------------------------------------------------------------------------------
|
|
24
|
+
SUPPORTED_LOCALES: List[LocaleCode] = [JA_JP, EN_US, DE_DE, BG_BG, FR_FR, IT_IT, ES_ES]
|
|
25
|
+
SUPPORTED_LANGUAGES: List[LanguageCode] = [JA, EN, DE, BG, FR, IT, ES]
|
|
26
|
+
LANGUAGE_LOCALE_MAPPING: Dict[LanguageCode, LocaleCode] = dict(list(zip(SUPPORTED_LANGUAGES, SUPPORTED_LOCALES)))
|
|
27
|
+
LOCALE_LANGUAGE_MAPPING: Dict[LocaleCode, LanguageCode] = dict(list(zip(SUPPORTED_LOCALES, SUPPORTED_LANGUAGES)))
|