kodexa 7.0.7909233749__py3-none-any.whl → 7.0.8003345991__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.
- kodexa/model/model.py +18 -12
- kodexa/model/objects.py +1 -0
- kodexa/model/persistence.py +1 -1
- kodexa/platform/client.py +9 -21
- kodexa/platform/kodexa.py +19 -79
- kodexa/testing/test_components.py +44 -1
- kodexa/testing/test_utils.py +2 -4
- {kodexa-7.0.7909233749.dist-info → kodexa-7.0.8003345991.dist-info}/METADATA +2 -2
- {kodexa-7.0.7909233749.dist-info → kodexa-7.0.8003345991.dist-info}/RECORD +11 -11
- {kodexa-7.0.7909233749.dist-info → kodexa-7.0.8003345991.dist-info}/LICENSE +0 -0
- {kodexa-7.0.7909233749.dist-info → kodexa-7.0.8003345991.dist-info}/WHEEL +0 -0
kodexa/model/model.py
CHANGED
@@ -8,11 +8,10 @@ import os
|
|
8
8
|
import re
|
9
9
|
import uuid
|
10
10
|
from enum import Enum
|
11
|
-
from typing import Any, List, Optional
|
11
|
+
from typing import Any, List, Optional, Dict
|
12
12
|
|
13
13
|
import deepdiff
|
14
14
|
import msgpack
|
15
|
-
from addict import Dict
|
16
15
|
from pydantic import BaseModel, ConfigDict
|
17
16
|
|
18
17
|
from kodexa.model.objects import ContentObject, FeatureSet
|
@@ -66,7 +65,9 @@ class Ref:
|
|
66
65
|
)
|
67
66
|
|
68
67
|
|
69
|
-
|
68
|
+
import addict
|
69
|
+
|
70
|
+
class DocumentMetadata(addict.Dict):
|
70
71
|
"""A flexible dict based approach to capturing metadata for the document.
|
71
72
|
|
72
73
|
This class extends from Dict to provide a flexible way to store and
|
@@ -83,7 +84,7 @@ class DocumentMetadata(Dict):
|
|
83
84
|
super().__init__(*args, **kwargs)
|
84
85
|
|
85
86
|
|
86
|
-
class ContentException(
|
87
|
+
class ContentException(dict):
|
87
88
|
"""A content exception represents an issue identified during labeling or validation at the document level.
|
88
89
|
|
89
90
|
Attributes:
|
@@ -129,7 +130,7 @@ class ContentException(Dict):
|
|
129
130
|
self.exception_type_id = exception_type_id
|
130
131
|
|
131
132
|
|
132
|
-
class Tag(
|
133
|
+
class Tag(dict):
|
133
134
|
"""A class to represent the metadata for a label that is applied as a feature on a content node.
|
134
135
|
|
135
136
|
Attributes:
|
@@ -387,7 +388,7 @@ class ContentNode(object):
|
|
387
388
|
return new_dict
|
388
389
|
|
389
390
|
@staticmethod
|
390
|
-
def from_dict(document, content_node_dict:
|
391
|
+
def from_dict(document, content_node_dict: dict, parent=None):
|
391
392
|
"""Build a new ContentNode from a dictionary represention.
|
392
393
|
|
393
394
|
Args:
|
@@ -2105,7 +2106,8 @@ class ContentFeature(object):
|
|
2105
2106
|
|
2106
2107
|
|
2107
2108
|
class ModelInsight(BaseModel):
|
2108
|
-
model_config = ConfigDict(populate_by_name=True, use_enum_values=True, arbitrary_types_allowed=True,
|
2109
|
+
model_config = ConfigDict(populate_by_name=True, use_enum_values=True, arbitrary_types_allowed=True,
|
2110
|
+
protected_namespaces=("model_config",))
|
2109
2111
|
"""
|
2110
2112
|
A class used to represent the insights of a model.
|
2111
2113
|
|
@@ -2449,7 +2451,7 @@ class Document(object):
|
|
2449
2451
|
"""
|
2450
2452
|
return self._persistence_layer.get_node_by_uuid(uuid)
|
2451
2453
|
|
2452
|
-
def add_tag_instance(self, tag_to_apply:str, node_list: List[ContentNode]):
|
2454
|
+
def add_tag_instance(self, tag_to_apply: str, node_list: List[ContentNode]):
|
2453
2455
|
"""
|
2454
2456
|
This will create a group of a tag with indexes
|
2455
2457
|
:param tag_to_apply: name of the tag
|
@@ -2955,8 +2957,10 @@ class Document(object):
|
|
2955
2957
|
Document.from_kdxa(file)
|
2956
2958
|
else:
|
2957
2959
|
file_document = Document()
|
2958
|
-
file_document.metadata
|
2959
|
-
file_document.metadata
|
2960
|
+
file_document.metadata["connector"] = "file-handle"
|
2961
|
+
file_document.metadata["connector_options"] = {};
|
2962
|
+
file_document.metadata["connector_options"]["file"] = file
|
2963
|
+
file_document.source
|
2960
2964
|
file_document.source.connector = "file-handle"
|
2961
2965
|
file_document.source.original_filename = os.path.basename(file)
|
2962
2966
|
file_document.source.original_path = file
|
@@ -2993,7 +2997,8 @@ class Document(object):
|
|
2993
2997
|
|
2994
2998
|
Args:
|
2995
2999
|
selector (str): The selector (ie. //*)
|
2996
|
-
variables (dict, optional): A dictionary of variable name/value to use in substituion; defaults to None.
|
3000
|
+
variables (dict, optional): A dictionary of variable name/value to use in substituion; defaults to None.
|
3001
|
+
Dictionary keys should match a variable specified in the selector.
|
2997
3002
|
|
2998
3003
|
Returns:
|
2999
3004
|
Optional[ContentNode]: The first matching node or none
|
@@ -3014,7 +3019,8 @@ class Document(object):
|
|
3014
3019
|
|
3015
3020
|
Args:
|
3016
3021
|
selector (str): The selector (ie. //*)
|
3017
|
-
variables (Optional[dict): A dictionary of variable name/value to use in substituion; defaults to an empty
|
3022
|
+
variables (Optional[dict): A dictionary of variable name/value to use in substituion; defaults to an empty
|
3023
|
+
dictionary. Dictionary keys should match a variable specified in the selector.
|
3018
3024
|
|
3019
3025
|
Returns:
|
3020
3026
|
list[ContentNodes]: A list of the matching ContentNodes. If no matches found, list is empty.
|
kodexa/model/objects.py
CHANGED
@@ -4237,6 +4237,7 @@ class Guidance(BaseModel):
|
|
4237
4237
|
document_page: Optional[int] = Field(None, alias="documentPage")
|
4238
4238
|
sample_text: Optional[str] = Field(None, alias="sampleText")
|
4239
4239
|
sample_result: Optional[Dict[str, List[GuidanceTagResult]]] = Field(None, alias="sampleResult")
|
4240
|
+
section_markers: Optional[List[GuidanceTagResult]] = Field(None, alias="sectionMarkers")
|
4240
4241
|
active: Optional[bool] = None
|
4241
4242
|
applicable_tags: Optional[List[str]] = Field(None, alias="applicableTags")
|
4242
4243
|
priority: Optional[int] = 1
|
kodexa/model/persistence.py
CHANGED
@@ -532,7 +532,7 @@ class SqliteDocumentPersistence(object):
|
|
532
532
|
"""
|
533
533
|
document_metadata = {
|
534
534
|
"version": Document.CURRENT_VERSION,
|
535
|
-
"metadata": self.document.metadata
|
535
|
+
"metadata": self.document.metadata,
|
536
536
|
"source": self.__clean_none_values(
|
537
537
|
dataclasses.asdict(self.document.source)
|
538
538
|
),
|
kodexa/platform/client.py
CHANGED
@@ -491,9 +491,9 @@ class ComponentEndpoint(ClientEndpoint, OrganizationOwned):
|
|
491
491
|
# Yield each endpoint in the current page
|
492
492
|
for endpoint in (
|
493
493
|
self.get_page_class(list_response.json())
|
494
|
-
|
495
|
-
|
496
|
-
|
494
|
+
.model_validate(list_response.json())
|
495
|
+
.set_client(self.client)
|
496
|
+
.to_endpoints()
|
497
497
|
):
|
498
498
|
yield endpoint
|
499
499
|
|
@@ -5551,7 +5551,6 @@ class ModelStoreEndpoint(DocumentStoreEndpoint):
|
|
5551
5551
|
response = self.client.get(url)
|
5552
5552
|
return ModelTraining.model_validate(response.json())
|
5553
5553
|
|
5554
|
-
|
5555
5554
|
def stream_list_trainings(self, query="*", sort=None, filters: List[str] = None):
|
5556
5555
|
"""
|
5557
5556
|
Stream the list of model trainings
|
@@ -5575,7 +5574,6 @@ class ModelStoreEndpoint(DocumentStoreEndpoint):
|
|
5575
5574
|
yield training
|
5576
5575
|
page += 1
|
5577
5576
|
|
5578
|
-
|
5579
5577
|
def list_trainings(
|
5580
5578
|
self, query="*", page=1, page_size=10, sort=None, filters: List[str] = None
|
5581
5579
|
) -> PageModelTraining:
|
@@ -6038,7 +6036,6 @@ class KodexaClient:
|
|
6038
6036
|
Attributes:
|
6039
6037
|
base_url (str): The base URL for the Kodexa platform.
|
6040
6038
|
access_token (str): The access token for the Kodexa platform.
|
6041
|
-
insecure (bool): A flag indicating whether the connection is insecure.
|
6042
6039
|
organizations (OrganizationsEndpoint): An endpoint for organizations.
|
6043
6040
|
projects (ProjectsEndpoint): An endpoint for projects.
|
6044
6041
|
workspaces (WorkspacesEndpoint): An endpoint for workspaces.
|
@@ -6049,7 +6046,7 @@ class KodexaClient:
|
|
6049
6046
|
messages (MessagesEndpoint): An endpoint for messages.
|
6050
6047
|
"""
|
6051
6048
|
|
6052
|
-
def __init__(self, url=None, access_token=None, profile=
|
6049
|
+
def __init__(self, url=None, access_token=None, profile="default"):
|
6053
6050
|
from kodexa import KodexaPlatform
|
6054
6051
|
|
6055
6052
|
self.base_url = url if url is not None else KodexaPlatform.get_url(profile)
|
@@ -6058,9 +6055,6 @@ class KodexaClient:
|
|
6058
6055
|
if access_token is not None
|
6059
6056
|
else KodexaPlatform.get_access_token(profile)
|
6060
6057
|
)
|
6061
|
-
self.insecure = (
|
6062
|
-
insecure if insecure is not None else KodexaPlatform.get_insecure(profile)
|
6063
|
-
)
|
6064
6058
|
self.organizations = OrganizationsEndpoint(self)
|
6065
6059
|
self.projects = ProjectsEndpoint(self)
|
6066
6060
|
self.workspaces = WorkspacesEndpoint(self)
|
@@ -6072,7 +6066,7 @@ class KodexaClient:
|
|
6072
6066
|
self.messages = MessagesEndpoint(self)
|
6073
6067
|
|
6074
6068
|
@staticmethod
|
6075
|
-
def login(url, email, password
|
6069
|
+
def login(url, email, password):
|
6076
6070
|
"""
|
6077
6071
|
A static method to login to the Kodexa platform.
|
6078
6072
|
|
@@ -6080,7 +6074,6 @@ class KodexaClient:
|
|
6080
6074
|
url (str): The URL for the Kodexa platform.
|
6081
6075
|
email (str): The email for the user.
|
6082
6076
|
password (str): The password for the user.
|
6083
|
-
insecure (bool, optional): A flag indicating whether the connection is insecure. Defaults to False.
|
6084
6077
|
|
6085
6078
|
Returns:
|
6086
6079
|
KodexaClient: A KodexaClient instance.
|
@@ -6093,11 +6086,10 @@ class KodexaClient:
|
|
6093
6086
|
obj_response = requests.get(
|
6094
6087
|
f"{url}/api/account/me/token",
|
6095
6088
|
auth=HTTPBasicAuth(email, password),
|
6096
|
-
headers={"content-type": "application/json"}
|
6097
|
-
verify=not insecure,
|
6089
|
+
headers={"content-type": "application/json"}
|
6098
6090
|
)
|
6099
6091
|
if obj_response.status_code == 200:
|
6100
|
-
return KodexaClient(url, obj_response.text
|
6092
|
+
return KodexaClient(url, obj_response.text)
|
6101
6093
|
|
6102
6094
|
raise Exception(f"Check your URL and password [{obj_response.status_code}]")
|
6103
6095
|
|
@@ -6253,8 +6245,7 @@ class KodexaClient:
|
|
6253
6245
|
headers={
|
6254
6246
|
"x-access-token": self.access_token,
|
6255
6247
|
"content-type": "application/json",
|
6256
|
-
}
|
6257
|
-
verify=not self.insecure,
|
6248
|
+
}
|
6258
6249
|
)
|
6259
6250
|
|
6260
6251
|
return process_response(response)
|
@@ -6286,7 +6277,6 @@ class KodexaClient:
|
|
6286
6277
|
files=files,
|
6287
6278
|
params=params,
|
6288
6279
|
headers=headers,
|
6289
|
-
verify=not self.insecure,
|
6290
6280
|
)
|
6291
6281
|
return process_response(response)
|
6292
6282
|
|
@@ -6317,7 +6307,6 @@ class KodexaClient:
|
|
6317
6307
|
files=files,
|
6318
6308
|
params=params,
|
6319
6309
|
headers=headers,
|
6320
|
-
verify=not self.insecure,
|
6321
6310
|
)
|
6322
6311
|
return process_response(response)
|
6323
6312
|
|
@@ -6335,8 +6324,7 @@ class KodexaClient:
|
|
6335
6324
|
response = requests.delete(
|
6336
6325
|
self.get_url(url),
|
6337
6326
|
params=params,
|
6338
|
-
headers={"x-access-token": self.access_token}
|
6339
|
-
verify=not self.insecure,
|
6327
|
+
headers={"x-access-token": self.access_token}
|
6340
6328
|
)
|
6341
6329
|
return process_response(response)
|
6342
6330
|
|
kodexa/platform/kodexa.py
CHANGED
@@ -12,6 +12,7 @@ import logging
|
|
12
12
|
import os
|
13
13
|
import time
|
14
14
|
from json import JSONDecodeError
|
15
|
+
from typing import Dict
|
15
16
|
|
16
17
|
import requests
|
17
18
|
from appdirs import AppDirs
|
@@ -38,7 +39,7 @@ logger = logging.getLogger()
|
|
38
39
|
dirs = AppDirs("Kodexa", "Kodexa")
|
39
40
|
|
40
41
|
|
41
|
-
def get_config(profile=
|
42
|
+
def get_config(profile="default"):
|
42
43
|
"""
|
43
44
|
Gets the kodexa config object used for local PAT storage.
|
44
45
|
|
@@ -55,24 +56,15 @@ def get_config(profile=None):
|
|
55
56
|
if os.path.exists(path):
|
56
57
|
with open(path, "r") as outfile:
|
57
58
|
kodexa_config = json.load(outfile)
|
58
|
-
if profile
|
59
|
+
if profile not in kodexa_config:
|
59
60
|
kodexa_config[profile] = {
|
60
61
|
"url": None,
|
61
62
|
"access_token": None,
|
62
|
-
"insecure": False,
|
63
63
|
}
|
64
|
-
|
65
|
-
if not profile and "insecure" not in kodexa_config:
|
66
|
-
kodexa_config["insecure"] = False
|
67
|
-
elif profile and "insecure" not in kodexa_config[profile]:
|
68
|
-
kodexa_config[profile]["insecure"] = False
|
69
|
-
|
70
64
|
return kodexa_config
|
71
65
|
else:
|
72
66
|
return (
|
73
|
-
{"url": None, "access_token": None
|
74
|
-
if not profile
|
75
|
-
else {profile: {"url": None, "access_token": None, "insecure": False}}
|
67
|
+
{profile: {"url": None, "access_token": None}}
|
76
68
|
)
|
77
69
|
|
78
70
|
|
@@ -128,7 +120,7 @@ class KodexaPlatform:
|
|
128
120
|
return KodexaClient(KodexaPlatform.get_url(), KodexaPlatform.get_access_token())
|
129
121
|
|
130
122
|
@staticmethod
|
131
|
-
def get_access_token(profile=
|
123
|
+
def get_access_token(profile="default") -> str:
|
132
124
|
"""
|
133
125
|
Get the access token.
|
134
126
|
|
@@ -144,12 +136,10 @@ class KodexaPlatform:
|
|
144
136
|
access_token
|
145
137
|
if access_token is not None
|
146
138
|
else kodexa_config[profile]["access_token"]
|
147
|
-
if profile
|
148
|
-
else kodexa_config["access_token"]
|
149
139
|
)
|
150
140
|
|
151
141
|
@staticmethod
|
152
|
-
def get_url(profile=
|
142
|
+
def get_url(profile="default") -> str:
|
153
143
|
"""
|
154
144
|
Get the URL to use to access a Kodexa Platform.
|
155
145
|
|
@@ -165,8 +155,6 @@ class KodexaPlatform:
|
|
165
155
|
env_url
|
166
156
|
if env_url is not None
|
167
157
|
else kodexa_config[profile]["url"]
|
168
|
-
if profile
|
169
|
-
else kodexa_config["url"]
|
170
158
|
)
|
171
159
|
|
172
160
|
@staticmethod
|
@@ -214,7 +202,7 @@ class KodexaPlatform:
|
|
214
202
|
return [org_slug, slug, version]
|
215
203
|
|
216
204
|
@classmethod
|
217
|
-
def configure(cls, kodexa_url, access_token, profile=
|
205
|
+
def configure(cls, kodexa_url, access_token, profile="default"):
|
218
206
|
"""
|
219
207
|
Configure kodexa access to platform
|
220
208
|
|
@@ -222,27 +210,17 @@ class KodexaPlatform:
|
|
222
210
|
kodexa_url (str): The URL of the Kodexa platform.
|
223
211
|
access_token (str): The access token to use.
|
224
212
|
profile (str, optional): The profile to use. Defaults to None.
|
225
|
-
insecure (bool, optional): Whether to use insecure connection. Defaults to False.
|
226
213
|
"""
|
227
214
|
kodexa_config = get_config(profile)
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
"access_token": access_token,
|
233
|
-
"insecure": insecure,
|
234
|
-
}
|
235
|
-
else:
|
236
|
-
kodexa_config = {
|
237
|
-
"url": kodexa_url,
|
238
|
-
"access_token": access_token,
|
239
|
-
"insecure": insecure
|
240
|
-
}
|
215
|
+
kodexa_config[profile] = {
|
216
|
+
"url": kodexa_url,
|
217
|
+
"access_token": access_token,
|
218
|
+
}
|
241
219
|
|
242
220
|
save_config(kodexa_config)
|
243
221
|
|
244
222
|
@classmethod
|
245
|
-
def login(cls, kodexa_url, username, password, profile=
|
223
|
+
def login(cls, kodexa_url, username, password, profile="default"):
|
246
224
|
"""
|
247
225
|
Login to the Kodexa platform.
|
248
226
|
|
@@ -251,26 +229,18 @@ class KodexaPlatform:
|
|
251
229
|
username (str): The username to use for login.
|
252
230
|
password (str): The password to use for login.
|
253
231
|
profile (str, optional): The profile to use. Defaults to None.
|
254
|
-
insecure (bool, optional): Whether to use insecure connection. Defaults to False.
|
255
232
|
"""
|
256
233
|
from requests.auth import HTTPBasicAuth
|
257
234
|
|
258
235
|
obj_response = requests.get(
|
259
236
|
f"{kodexa_url}/api/account/me/token",
|
260
237
|
auth=HTTPBasicAuth(username, password),
|
261
|
-
headers={"content-type": "application/json"}
|
262
|
-
verify=not insecure,
|
238
|
+
headers={"content-type": "application/json"}
|
263
239
|
)
|
264
240
|
if obj_response.status_code == 200:
|
265
241
|
kodexa_config = get_config(profile)
|
266
|
-
|
267
|
-
|
268
|
-
kodexa_config[profile]["access_token"] = obj_response.text
|
269
|
-
kodexa_config[profile]["insecure"] = insecure
|
270
|
-
else:
|
271
|
-
kodexa_config["url"] = kodexa_url
|
272
|
-
kodexa_config["access_token"] = obj_response.text
|
273
|
-
kodexa_config["insecure"] = insecure
|
242
|
+
kodexa_config[profile]["url"] = kodexa_url
|
243
|
+
kodexa_config[profile]["access_token"] = obj_response.text
|
274
244
|
save_config(kodexa_config)
|
275
245
|
print("Logged in")
|
276
246
|
else:
|
@@ -290,7 +260,6 @@ class KodexaPlatform:
|
|
290
260
|
"x-access-token": KodexaPlatform.get_access_token(),
|
291
261
|
"content-type": "application/json",
|
292
262
|
},
|
293
|
-
verify=not KodexaPlatform.get_insecure(),
|
294
263
|
)
|
295
264
|
if r.status_code == 401:
|
296
265
|
raise Exception("Your access token was not authorized")
|
@@ -314,27 +283,6 @@ class KodexaPlatform:
|
|
314
283
|
|
315
284
|
return os.getenv("KODEXA_TMP", tempfile.gettempdir())
|
316
285
|
|
317
|
-
@classmethod
|
318
|
-
def get_insecure(cls, profile=None):
|
319
|
-
"""
|
320
|
-
Get the insecure setting.
|
321
|
-
|
322
|
-
Args:
|
323
|
-
profile (str, optional): The profile to use. Defaults to None.
|
324
|
-
|
325
|
-
Returns:
|
326
|
-
bool: The insecure setting.
|
327
|
-
"""
|
328
|
-
kodexa_config = get_config(profile)
|
329
|
-
insecure = os.getenv("KODEXA_URL_INSECURE", None)
|
330
|
-
return (
|
331
|
-
insecure
|
332
|
-
if insecure is not None
|
333
|
-
else kodexa_config[profile]["insecure"]
|
334
|
-
if profile
|
335
|
-
else kodexa_config["insecure"]
|
336
|
-
)
|
337
|
-
|
338
286
|
|
339
287
|
class RemoteSession:
|
340
288
|
"""A Session on the Kodexa platform for leveraging pipelines and services"""
|
@@ -360,7 +308,6 @@ class RemoteSession:
|
|
360
308
|
r = requests.get(
|
361
309
|
f"{KodexaPlatform.get_url()}/api/actions/{ref.replace(':', '/')}",
|
362
310
|
headers={"x-access-token": KodexaPlatform.get_access_token()},
|
363
|
-
verify=not KodexaPlatform.get_insecure(),
|
364
311
|
)
|
365
312
|
if r.status_code == 401:
|
366
313
|
raise Exception("Your access token was not authorized")
|
@@ -381,7 +328,6 @@ class RemoteSession:
|
|
381
328
|
f"{KodexaPlatform.get_url()}/api/sessions",
|
382
329
|
params={self.session_type: self.slug},
|
383
330
|
headers={"x-access-token": KodexaPlatform.get_access_token()},
|
384
|
-
verify=not KodexaPlatform.get_insecure(),
|
385
331
|
)
|
386
332
|
|
387
333
|
process_response(r)
|
@@ -422,11 +368,10 @@ class RemoteSession:
|
|
422
368
|
data=data,
|
423
369
|
headers={"x-access-token": KodexaPlatform.get_access_token()},
|
424
370
|
files=files,
|
425
|
-
verify=not KodexaPlatform.get_insecure(),
|
426
371
|
)
|
427
372
|
try:
|
428
373
|
if r.status_code == 200:
|
429
|
-
execution =
|
374
|
+
execution = json.loads(r.text)
|
430
375
|
else:
|
431
376
|
logger.warning(
|
432
377
|
"Execution creation failed ["
|
@@ -466,10 +411,9 @@ class RemoteSession:
|
|
466
411
|
r = requests.get(
|
467
412
|
f"{KodexaPlatform.get_url()}/api/sessions/{self.cloud_session.id}/executions/{execution.id}",
|
468
413
|
headers={"x-access-token": KodexaPlatform.get_access_token()},
|
469
|
-
verify=not KodexaPlatform.get_insecure(),
|
470
414
|
)
|
471
415
|
try:
|
472
|
-
execution =
|
416
|
+
execution = json.loads(r.text)
|
473
417
|
except JSONDecodeError:
|
474
418
|
logger.warning("Unable to handle response [" + r.text + "]")
|
475
419
|
raise
|
@@ -523,7 +467,6 @@ class RemoteSession:
|
|
523
467
|
doc = requests.get(
|
524
468
|
f"{KodexaPlatform.get_url()}/api/sessions/{self.cloud_session.id}/executions/{execution.id}/objects/{execution.outputId}",
|
525
469
|
headers={"x-access-token": KodexaPlatform.get_access_token()},
|
526
|
-
verify=KodexaPlatform.get_insecure(),
|
527
470
|
)
|
528
471
|
return Document.from_kddb(doc.content)
|
529
472
|
|
@@ -813,7 +756,6 @@ class EventHelper:
|
|
813
756
|
json=[{"entry": message}],
|
814
757
|
headers={"x-access-token": KodexaPlatform.get_access_token()},
|
815
758
|
timeout=300,
|
816
|
-
verify=not KodexaPlatform.get_insecure(),
|
817
759
|
)
|
818
760
|
if response.status_code != 200:
|
819
761
|
print(f"Logging failed {response.status_code}", flush=True)
|
@@ -837,8 +779,7 @@ class EventHelper:
|
|
837
779
|
co_response = requests.get(
|
838
780
|
f"{KodexaPlatform.get_url()}/api/sessions/{self.event.session_id}/executions/{self.event.execution.id}/objects/{content_object_id}",
|
839
781
|
headers={"x-access-token": KodexaPlatform.get_access_token()},
|
840
|
-
timeout=300
|
841
|
-
verify=not KodexaPlatform.get_insecure(),
|
782
|
+
timeout=300
|
842
783
|
)
|
843
784
|
process_response(co_response)
|
844
785
|
return io.BytesIO(co_response.content)
|
@@ -866,8 +807,7 @@ class EventHelper:
|
|
866
807
|
data=data,
|
867
808
|
headers={"x-access-token": KodexaPlatform.get_access_token()},
|
868
809
|
files=files,
|
869
|
-
timeout=300
|
870
|
-
verify=not KodexaPlatform.get_insecure(),
|
810
|
+
timeout=300
|
871
811
|
)
|
872
812
|
|
873
813
|
process_response(co_response)
|
@@ -1,3 +1,6 @@
|
|
1
|
+
import os
|
2
|
+
|
3
|
+
from kodexa import KodexaClient, KodexaPlatform
|
1
4
|
from kodexa.assistant import (
|
2
5
|
Assistant,
|
3
6
|
AssistantContext,
|
@@ -19,7 +22,7 @@ class TestAssistant(Assistant):
|
|
19
22
|
""" """
|
20
23
|
|
21
24
|
def process_event(
|
22
|
-
|
25
|
+
self, event: BaseEvent, context: AssistantContext = None
|
23
26
|
) -> AssistantResponse:
|
24
27
|
"""
|
25
28
|
|
@@ -40,3 +43,43 @@ class TestAssistant(Assistant):
|
|
40
43
|
return AssistantResponse(
|
41
44
|
pipelines=[AssistantPipeline(pipeline=pipeline, write_back_to_store=True)]
|
42
45
|
)
|
46
|
+
|
47
|
+
|
48
|
+
def test_profile_default():
|
49
|
+
"""
|
50
|
+
:assert: Checks if the default profile is set correctly
|
51
|
+
"""
|
52
|
+
kodexa_url = os.getenv("URL")
|
53
|
+
access_token = os.getenv("ACCESS_TOKEN")
|
54
|
+
KodexaPlatform.configure(kodexa_url, access_token)
|
55
|
+
assert KodexaPlatform.get_url() == kodexa_url and KodexaPlatform.get_access_token() == access_token
|
56
|
+
|
57
|
+
|
58
|
+
def test_profile_custom():
|
59
|
+
"""
|
60
|
+
:assert: Checks if the custom profile is set correctly
|
61
|
+
"""
|
62
|
+
kodexa_url = os.getenv("URL")
|
63
|
+
access_token = os.getenv("ACCESS_TOKEN")
|
64
|
+
profile = "dev-profile"
|
65
|
+
KodexaPlatform.configure(kodexa_url, access_token, profile)
|
66
|
+
assert KodexaPlatform.get_url(profile) == kodexa_url and KodexaPlatform.get_access_token(profile) == access_token
|
67
|
+
|
68
|
+
|
69
|
+
def test_kodexa_client_default_profile():
|
70
|
+
kodexa_cli = KodexaClient()
|
71
|
+
assert kodexa_cli.base_url == KodexaPlatform.get_url("default") and \
|
72
|
+
kodexa_cli.access_token == KodexaPlatform.get_access_token("default")
|
73
|
+
|
74
|
+
|
75
|
+
def test_kodexa_client_custom_profile():
|
76
|
+
kodexa_cli = KodexaClient(profile="dev-profile")
|
77
|
+
assert kodexa_cli.base_url == KodexaPlatform.get_url("dev-profile") and \
|
78
|
+
kodexa_cli.access_token == KodexaPlatform.get_access_token("dev-profile")
|
79
|
+
|
80
|
+
|
81
|
+
def test_customized_kodexe_client():
|
82
|
+
kodexa_url = "https://test.test.com"
|
83
|
+
access_token = "test-token"
|
84
|
+
kodexa_cli = KodexaClient(kodexa_url, access_token)
|
85
|
+
assert kodexa_cli.base_url != KodexaPlatform.get_url() and kodexa_cli.access_token != KodexaPlatform.get_access_token()
|
kodexa/testing/test_utils.py
CHANGED
@@ -3,8 +3,6 @@ import importlib
|
|
3
3
|
import logging
|
4
4
|
from typing import List
|
5
5
|
|
6
|
-
from addict import addict
|
7
|
-
|
8
6
|
from kodexa import Assistant, AssistantResponse
|
9
7
|
from kodexa import (
|
10
8
|
ContentEvent,
|
@@ -312,13 +310,13 @@ class ExtensionPackUtil:
|
|
312
310
|
import yaml
|
313
311
|
|
314
312
|
with open(file_path, "r") as stream:
|
315
|
-
self.kodexa_metadata =
|
313
|
+
self.kodexa_metadata = yaml.safe_load(stream)
|
316
314
|
|
317
315
|
if file_path.endswith(".json"):
|
318
316
|
import json
|
319
317
|
|
320
318
|
with open(file_path, "r") as stream:
|
321
|
-
self.kodexa_metadata =
|
319
|
+
self.kodexa_metadata = json.load(stream)
|
322
320
|
|
323
321
|
def get_step(self, action_slug, options=None):
|
324
322
|
"""
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: kodexa
|
3
|
-
Version: 7.0.
|
3
|
+
Version: 7.0.8003345991
|
4
4
|
Summary: Python SDK for the Kodexa Platform
|
5
5
|
Author: Austin Redenbaugh
|
6
6
|
Author-email: austin@kodexa.com
|
@@ -13,7 +13,7 @@ Classifier: Programming Language :: Python :: 3.9
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.10
|
14
14
|
Classifier: Programming Language :: Python :: 3.11
|
15
15
|
Classifier: Topic :: Software Development :: Libraries
|
16
|
-
Requires-Dist: addict (
|
16
|
+
Requires-Dist: addict (>=2.4.0,<3.0.0)
|
17
17
|
Requires-Dist: appdirs (>=1.4.4,<2.0.0)
|
18
18
|
Requires-Dist: better-exceptions (>=0.3.3,<0.4.0)
|
19
19
|
Requires-Dist: chevron (>=0.14.0,<0.15.0)
|
@@ -5,15 +5,15 @@ kodexa/connectors/__init__.py,sha256=WF6G_MUeU32TlKSUKkpNoNX7dq8iBPliFMep4E8BmZc
|
|
5
5
|
kodexa/connectors/connectors.py,sha256=FpUZDkSyHld2b9eYRuVOWzaFtuGoaRuPXXicJB7THbc,10413
|
6
6
|
kodexa/model/__init__.py,sha256=rtLXYJBxB-rnukhslN9rlqoB3--1H3253HyHGbD_Gc8,796
|
7
7
|
kodexa/model/base.py,sha256=CaZK8nMhT1LdCpt4aLhebJGcorjq9qRID1FjnXnP14M,521
|
8
|
-
kodexa/model/model.py,sha256=
|
9
|
-
kodexa/model/objects.py,sha256=
|
10
|
-
kodexa/model/persistence.py,sha256=
|
8
|
+
kodexa/model/model.py,sha256=Bghea55_XvALtro3_Z3fXsEjGmK2_dTKgPOOC8ZEyyo,115050
|
9
|
+
kodexa/model/objects.py,sha256=SrLXuEmy2nEDDN09uza-o3A_Ww7qp3P7wSt_fq_a3r0,171871
|
10
|
+
kodexa/model/persistence.py,sha256=JW7CmEyyMfk4h7tWFn5Dj21nFExaeNv8OE7wD6Q7Khs,59492
|
11
11
|
kodexa/pipeline/__init__.py,sha256=sA7f5D6qkdMrpp2xTIeefnrUBI6xxEEWostvxfX_1Cs,236
|
12
12
|
kodexa/pipeline/pipeline.py,sha256=cIRFOoJkguIYgNzx6FYrODdBpcY25CM_SULsqSsHeXE,24323
|
13
13
|
kodexa/platform/__init__.py,sha256=1O3oiWMg292NPL_NacKDnK1T3_R6cMorrPRue_9e-O4,216
|
14
|
-
kodexa/platform/client.py,sha256
|
14
|
+
kodexa/platform/client.py,sha256=-TAVAwgV8jWzZ8yG8Ve8c51J5VbGkqmeN4Qk4Ii9nVw,209681
|
15
15
|
kodexa/platform/interaction.py,sha256=6zpcwXKNZstUGNS6m4JsoRXAqCZPJHWI-ZN3co8nnF0,1055
|
16
|
-
kodexa/platform/kodexa.py,sha256=
|
16
|
+
kodexa/platform/kodexa.py,sha256=UOEyc6fNPx-I5Bg21Bzj5s5R4-W3PVMeJBFX7cnXPKA,30888
|
17
17
|
kodexa/selectors/__init__.py,sha256=xA9-4vpyaAZWPSk3bh2kvDLkdv6XEmm7PjFbpziiTIk,100
|
18
18
|
kodexa/selectors/ast.py,sha256=gG-1st841IntgBE5V7p3Cq9azaym2jV5lB_AIywQTCI,13269
|
19
19
|
kodexa/selectors/core.py,sha256=kkt02DN20gXeaDGoGubPPeeTV7rCr4sxTyELrI0l1YU,3691
|
@@ -31,11 +31,11 @@ kodexa/spatial/table_form_common.py,sha256=qJIqr6INNFTe8EPrXchZ9a1ZgS9dZnhx_wgvd
|
|
31
31
|
kodexa/steps/__init__.py,sha256=qpmAtYePTv7G-HzUBx087bA3kq-PPGcFJf4_Z5P--0k,179
|
32
32
|
kodexa/steps/common.py,sha256=fGEuKxcztcqrYFpXbu_OYkxh42yR9s5mkszmtkJhnQ8,10428
|
33
33
|
kodexa/testing/__init__.py,sha256=P8W-SOnWsi48asfnQV06iyHrzZAzuX69j9oYwBvgp5s,323
|
34
|
-
kodexa/testing/test_components.py,sha256=
|
35
|
-
kodexa/testing/test_utils.py,sha256=
|
34
|
+
kodexa/testing/test_components.py,sha256=qGFHUN6nm6bEOa2ZCN0jDUWsCHRnEcjdcHSRetgIr-E,2571
|
35
|
+
kodexa/testing/test_utils.py,sha256=2ioYPXeyvVkE-u5VtgFMW0AyGTvplERgmnKXELAffbY,13990
|
36
36
|
kodexa/training/__init__.py,sha256=xs2L62YpRkIRfslQwtQZ5Yxjhm7sLzX2TrVX6EuBnZQ,52
|
37
37
|
kodexa/training/train_utils.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
38
|
-
kodexa-7.0.
|
39
|
-
kodexa-7.0.
|
40
|
-
kodexa-7.0.
|
41
|
-
kodexa-7.0.
|
38
|
+
kodexa-7.0.8003345991.dist-info/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
|
39
|
+
kodexa-7.0.8003345991.dist-info/METADATA,sha256=xve3b8zHnzr_kjAlIwQJzWQUUvwJzWQTh6NDhvGluDI,4074
|
40
|
+
kodexa-7.0.8003345991.dist-info/WHEEL,sha256=Zb28QaM1gQi8f4VCBhsUklF61CTlNYfs9YAZn-TOGFk,88
|
41
|
+
kodexa-7.0.8003345991.dist-info/RECORD,,
|
File without changes
|
File without changes
|