kodexa 7.0.1a8003211616__py3-none-any.whl → 7.0.1a9196667375__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/entities/__init__.py +0 -0
- kodexa/model/entities/product.py +126 -0
- kodexa/model/entities/product_subscription.py +122 -0
- kodexa/model/model.py +26 -7
- kodexa/model/objects.py +135 -47
- kodexa/model/persistence.py +96 -34
- kodexa/pipeline/pipeline.py +30 -10
- kodexa/platform/client.py +241 -42
- kodexa/platform/kodexa.py +117 -32
- kodexa/testing/test_components.py +0 -40
- kodexa/testing/test_utils.py +3 -1
- {kodexa-7.0.1a8003211616.dist-info → kodexa-7.0.1a9196667375.dist-info}/METADATA +4 -15
- {kodexa-7.0.1a8003211616.dist-info → kodexa-7.0.1a9196667375.dist-info}/RECORD +15 -12
- {kodexa-7.0.1a8003211616.dist-info → kodexa-7.0.1a9196667375.dist-info}/LICENSE +0 -0
- {kodexa-7.0.1a8003211616.dist-info → kodexa-7.0.1a9196667375.dist-info}/WHEEL +0 -0
kodexa/platform/client.py
CHANGED
@@ -85,7 +85,7 @@ from kodexa.model.objects import (
|
|
85
85
|
ReprocessRequest,
|
86
86
|
PageExtensionPack,
|
87
87
|
PageOrganization,
|
88
|
-
DocumentFamilyStatistics, MessageContext, PagePrompt, Prompt, GuidanceSet, PageGuidanceSet,
|
88
|
+
DocumentFamilyStatistics, MessageContext, PagePrompt, Prompt, GuidanceSet, PageGuidanceSet, DocumentEmbedding,
|
89
89
|
)
|
90
90
|
|
91
91
|
logger = logging.getLogger()
|
@@ -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
|
|
@@ -548,7 +548,7 @@ class ComponentEndpoint(ClientEndpoint, OrganizationOwned):
|
|
548
548
|
Returns:
|
549
549
|
The created component.
|
550
550
|
"""
|
551
|
-
url = f"/api/{self.get_type()}/{self.organization.slug}
|
551
|
+
url = f"/api/{self.get_type()}/{self.organization.slug}"
|
552
552
|
get_response = self.client.post(
|
553
553
|
url, component.model_dump(mode="json", by_alias=True)
|
554
554
|
)
|
@@ -774,7 +774,7 @@ class EntitiesEndpoint:
|
|
774
774
|
Returns:
|
775
775
|
PageProject: The page of projects belonging to the organization.
|
776
776
|
"""
|
777
|
-
url = f"/api/{self.get_type()}
|
777
|
+
url = f"/api/{self.get_type()}"
|
778
778
|
get_response = self.client.get(
|
779
779
|
url, params={"filter": f"organization.id: '{organization.id}'"}
|
780
780
|
)
|
@@ -1598,6 +1598,83 @@ class OrganizationEndpoint(Organization, EntityEndpoint):
|
|
1598
1598
|
"""
|
1599
1599
|
return TaxonomiesEndpoint().set_client(self.client).set_organization(self)
|
1600
1600
|
|
1601
|
+
@property
|
1602
|
+
def available_templates(self, page=1, page_size=10, query="*"):
|
1603
|
+
"""
|
1604
|
+
Get the available templates for the organization.
|
1605
|
+
|
1606
|
+
Returns:
|
1607
|
+
MarketplaceEndpoint: The marketplace endpoint of the organization.
|
1608
|
+
"""
|
1609
|
+
url = f"/api/organizations/{self.id}/availableTemplates"
|
1610
|
+
response = self.client.get(url, params={"page": page, "pageSize": page_size, "query": query})
|
1611
|
+
return PageProjectTemplateEndpoint.model_validate(response.json()).set_client(self.client)
|
1612
|
+
|
1613
|
+
@property
|
1614
|
+
def available_models(self, page=1, page_size=10, query="*"):
|
1615
|
+
"""
|
1616
|
+
Get the available models for the organization.
|
1617
|
+
|
1618
|
+
Returns:
|
1619
|
+
MarketplaceEndpoint: The marketplace endpoint of the organization.
|
1620
|
+
"""
|
1621
|
+
url = f"/api/organizations/{self.id}/availableModels"
|
1622
|
+
response = self.client.get(url, params={"page": page, "pageSize": page_size, "query": query})
|
1623
|
+
return PageStoreEndpoint.model_validate(response.json()).set_client(self.client)
|
1624
|
+
|
1625
|
+
@property
|
1626
|
+
def available_assistants(self, page=1, page_size=10, query="*"):
|
1627
|
+
"""
|
1628
|
+
Get the available assistants for the organization.
|
1629
|
+
|
1630
|
+
Returns:
|
1631
|
+
MarketplaceEndpoint: The marketplace endpoint of the organization.
|
1632
|
+
"""
|
1633
|
+
url = f"/api/organizations/{self.id}/availableAssistants"
|
1634
|
+
response = self.client.get(url, params={"page": page, "pageSize": page_size, "query": query})
|
1635
|
+
return PageAssistantDefinitionEndpoint.model_validate(response.json()).set_client(self.client)
|
1636
|
+
|
1637
|
+
def get_subscriptions(self, page: int = 1, page_size: int = 10) -> "PageProductSubscriptionEndpoint":
|
1638
|
+
"""
|
1639
|
+
Get the subscriptions of the organization.
|
1640
|
+
|
1641
|
+
Returns:
|
1642
|
+
The subscriptions of the organization.
|
1643
|
+
"""
|
1644
|
+
url = f"/api/productSubscriptions"
|
1645
|
+
params = {
|
1646
|
+
"filter": f"organization.id: '{self.id}'",
|
1647
|
+
"page": page,
|
1648
|
+
"pageSize": page_size
|
1649
|
+
}
|
1650
|
+
response = self.client.get(url, params=params)
|
1651
|
+
|
1652
|
+
from kodexa.model.entities.product_subscription import PageProductSubscriptionEndpoint
|
1653
|
+
return PageProductSubscriptionEndpoint.model_validate(response.json()).set_client(self.client)
|
1654
|
+
|
1655
|
+
def remove_subscription(self, subscription: "ProductSubscription") -> None:
|
1656
|
+
"""
|
1657
|
+
Remove a subscription from the organization.
|
1658
|
+
|
1659
|
+
Args:
|
1660
|
+
subscription_id (str): The id of the subscription to remove.
|
1661
|
+
"""
|
1662
|
+
url = f"/api/productSubscriptions/{subscription.id}"
|
1663
|
+
self.client.delete(url)
|
1664
|
+
|
1665
|
+
def add_subscription(self, product: "Product") -> None:
|
1666
|
+
"""
|
1667
|
+
Add a subscription to the organization.
|
1668
|
+
|
1669
|
+
Args:
|
1670
|
+
product (Product): The product to subscribe to.
|
1671
|
+
"""
|
1672
|
+
url = f"/api/productSubscriptions"
|
1673
|
+
from kodexa.model.entities.product_subscription import ProductSubscription
|
1674
|
+
new_product_subscription = ProductSubscription(organization=self.detach(), product=product)
|
1675
|
+
print(new_product_subscription.model_dump_json(by_alias=True))
|
1676
|
+
self.client.post(url, body=json.loads(new_product_subscription.model_dump_json(by_alias=True)))
|
1677
|
+
|
1601
1678
|
|
1602
1679
|
class ComponentsEndpoint(ClientEndpoint):
|
1603
1680
|
"""
|
@@ -1725,13 +1802,15 @@ class ComponentInstanceEndpoint(ClientEndpoint, SlugBasedMetadata):
|
|
1725
1802
|
raise Exception(f"Component {self.ref} already exists")
|
1726
1803
|
|
1727
1804
|
if exists:
|
1728
|
-
self.client.put(url, self.model_dump(mode="json", by_alias=True))
|
1805
|
+
response = self.client.put(url, self.model_dump(mode="json", by_alias=True))
|
1806
|
+
process_response(response)
|
1729
1807
|
return self.post_deploy()
|
1730
1808
|
|
1731
|
-
self.client.post(
|
1809
|
+
response = self.client.post(
|
1732
1810
|
f"/api/{self.get_type()}/{self.org_slug}",
|
1733
1811
|
self.model_dump(mode="json", by_alias=True),
|
1734
1812
|
)
|
1813
|
+
process_response(response)
|
1735
1814
|
return self.post_deploy()
|
1736
1815
|
|
1737
1816
|
|
@@ -2072,6 +2151,33 @@ class ProjectTaxonomiesEndpoint(ProjectResourceEndpoint):
|
|
2072
2151
|
return TaxonomyEndpoint
|
2073
2152
|
|
2074
2153
|
|
2154
|
+
class ProjectGuidanceSetsEndpoint(ProjectResourceEndpoint):
|
2155
|
+
|
2156
|
+
def get_type(self) -> str:
|
2157
|
+
return "guidance"
|
2158
|
+
|
2159
|
+
def get_instance_class(self, object_dict=None):
|
2160
|
+
return GuidanceSetsEndpoint
|
2161
|
+
|
2162
|
+
|
2163
|
+
class ProjectDataFormEndpoint(ProjectResourceEndpoint):
|
2164
|
+
|
2165
|
+
def get_type(self) -> str:
|
2166
|
+
return "dataForms"
|
2167
|
+
|
2168
|
+
def get_instance_class(self, object_dict=None):
|
2169
|
+
return DataFormEndpoint
|
2170
|
+
|
2171
|
+
|
2172
|
+
class ProjectDashboardEndpoint(ProjectResourceEndpoint):
|
2173
|
+
|
2174
|
+
def get_type(self) -> str:
|
2175
|
+
return "dashboards"
|
2176
|
+
|
2177
|
+
def get_instance_class(self, object_dict=None):
|
2178
|
+
return DashboardEndpoint
|
2179
|
+
|
2180
|
+
|
2075
2181
|
class ProjectStoresEndpoint(ProjectResourceEndpoint):
|
2076
2182
|
"""Represents a project stores endpoint"""
|
2077
2183
|
|
@@ -2352,20 +2458,25 @@ class ProjectEndpoint(EntityEndpoint, Project):
|
|
2352
2458
|
self,
|
2353
2459
|
stores: List["StoreEndpoint"] = None,
|
2354
2460
|
taxonomies: List["TaxonomyEndpoint"] = None,
|
2355
|
-
|
2461
|
+
data_forms: List["DataFormEndpoint"] = None,
|
2462
|
+
guidance: List["GuidanceSetsEndpoint"] = None,
|
2463
|
+
dashboards: List["DashboardEndpoint"] = None,
|
2464
|
+
):
|
2356
2465
|
"""Update the resources of the project.
|
2357
2466
|
|
2358
2467
|
Args:
|
2359
2468
|
stores (List["StoreEndpoint"], optional): List of store endpoints to update.
|
2360
2469
|
taxonomies (List["TaxonomyEndpoint"], optional): List of taxonomy endpoints to update.
|
2361
|
-
|
2362
|
-
|
2363
|
-
|
2470
|
+
data_forms (List["DataFormEndpoint"], optional): List of data form endpoints to update.
|
2471
|
+
guidance (List["GuidanceSetEndpoint"], optional): List of guidance set endpoints to update.
|
2472
|
+
dashboards (List["DashboardEndpoint"], optional): List of dashboard endpoints to update.
|
2364
2473
|
"""
|
2365
2474
|
project_resources_update = ProjectResourcesUpdate()
|
2366
2475
|
project_resources_update.store_refs = []
|
2367
2476
|
project_resources_update.taxonomy_refs = []
|
2368
2477
|
project_resources_update.dashboard_refs = []
|
2478
|
+
project_resources_update.data_form_refs = []
|
2479
|
+
project_resources_update.guidance_set_refs = []
|
2369
2480
|
|
2370
2481
|
if stores:
|
2371
2482
|
project_resources_update.store_refs = [store.ref for store in stores]
|
@@ -2374,6 +2485,18 @@ class ProjectEndpoint(EntityEndpoint, Project):
|
|
2374
2485
|
project_resources_update.taxonomy_refs = [
|
2375
2486
|
taxonomy.ref for taxonomy in taxonomies
|
2376
2487
|
]
|
2488
|
+
if data_forms:
|
2489
|
+
project_resources_update.data_form_refs = [
|
2490
|
+
data_form.ref for data_form in data_forms
|
2491
|
+
]
|
2492
|
+
if guidance:
|
2493
|
+
project_resources_update.guidance_set_refs = [
|
2494
|
+
guidance.ref for guidance in guidance
|
2495
|
+
]
|
2496
|
+
if dashboards:
|
2497
|
+
project_resources_update.dashboard_refs = [
|
2498
|
+
dashboard.ref for dashboard in dashboards
|
2499
|
+
]
|
2377
2500
|
|
2378
2501
|
self.client.put(
|
2379
2502
|
f"/api/projects/{self.id}/resources",
|
@@ -2416,6 +2539,15 @@ class ProjectEndpoint(EntityEndpoint, Project):
|
|
2416
2539
|
"""
|
2417
2540
|
return ProjectTaxonomiesEndpoint().set_client(self.client).set_project(self)
|
2418
2541
|
|
2542
|
+
@property
|
2543
|
+
def guidance(self) -> "ProjectGuidanceEndpoint":
|
2544
|
+
"""Get the guidance sets endpoint of the project.
|
2545
|
+
|
2546
|
+
Returns:
|
2547
|
+
GuidanceSetsEndpoint: The guidance sets endpoint of the project.
|
2548
|
+
"""
|
2549
|
+
return ProjectGuidanceSetEndpoint().set_client(self.client).set_project(self)
|
2550
|
+
|
2419
2551
|
@property
|
2420
2552
|
def assistants(self) -> ProjectAssistantsEndpoint:
|
2421
2553
|
"""Get the assistants endpoint of the project.
|
@@ -2450,6 +2582,7 @@ class ProjectEndpoint(EntityEndpoint, Project):
|
|
2450
2582
|
return [ProjectTag.model_validate(tag) for tag in response.json()]
|
2451
2583
|
|
2452
2584
|
|
2585
|
+
|
2453
2586
|
class MessagesEndpoint(EntitiesEndpoint):
|
2454
2587
|
"""Represents a message endpoint"""
|
2455
2588
|
|
@@ -2652,12 +2785,13 @@ class ProjectsEndpoint(EntitiesEndpoint):
|
|
2652
2785
|
"""
|
2653
2786
|
return PageProjectEndpoint
|
2654
2787
|
|
2655
|
-
def find_by_name(self, project_name: str) -> Optional[ProjectEndpoint]:
|
2788
|
+
def find_by_name(self, project_name: str, organization: Optional[Organization] = None) -> Optional[ProjectEndpoint]:
|
2656
2789
|
"""
|
2657
2790
|
Find a project by name.
|
2658
2791
|
|
2659
2792
|
Args:
|
2660
2793
|
project_name (str): The name of the project to find.
|
2794
|
+
organization (Organization, optional): The organization to search in. Defaults to None.
|
2661
2795
|
|
2662
2796
|
Returns:
|
2663
2797
|
Optional[ProjectEndpoint]: The project endpoint if found, None otherwise.
|
@@ -2665,8 +2799,8 @@ class ProjectsEndpoint(EntitiesEndpoint):
|
|
2665
2799
|
|
2666
2800
|
url = f"/api/{self.get_type()}"
|
2667
2801
|
filters = {"filter": [f"name: '{project_name}'"]}
|
2668
|
-
if
|
2669
|
-
filters["filter"].append(f"organization.id: '{
|
2802
|
+
if organization is not None:
|
2803
|
+
filters["filter"].append(f"organization.id: '{organization.id}'")
|
2670
2804
|
get_response = self.client.get(url, params=filters)
|
2671
2805
|
if len(get_response.json()["content"]) > 0:
|
2672
2806
|
return ProjectEndpoint.model_validate(
|
@@ -2734,7 +2868,7 @@ class ProjectsEndpoint(EntitiesEndpoint):
|
|
2734
2868
|
if self.organization is not None:
|
2735
2869
|
params["filter"].append(f"organization.id: '{self.organization.id}'")
|
2736
2870
|
|
2737
|
-
get_response = self.client.get(f"/api/{self.get_type()}
|
2871
|
+
get_response = self.client.get(f"/api/{self.get_type()}", params=params)
|
2738
2872
|
|
2739
2873
|
return PageProjectEndpoint.model_validate(get_response.json()).set_client(
|
2740
2874
|
self.client
|
@@ -2833,20 +2967,21 @@ class StoresEndpoint(ComponentEndpoint, ClientEndpoint, OrganizationOwned):
|
|
2833
2967
|
raise ValueError(f"Unknown store type {object_dict['storeType']}")
|
2834
2968
|
|
2835
2969
|
|
2836
|
-
class
|
2970
|
+
class GuidanceSetsEndpoint(ComponentEndpoint, ClientEndpoint, OrganizationOwned):
|
2837
2971
|
"""
|
2838
|
-
Represents a guidance endpoint.
|
2972
|
+
Represents a guidance set endpoint.
|
2839
2973
|
|
2840
|
-
This class is used to interact with the
|
2974
|
+
This class is used to interact with the guidance endpoint of the API.
|
2841
2975
|
It provides methods to get the type, page class, and instance class of the endpoint,
|
2842
2976
|
as well as to deploy an extension pack from a URL.
|
2843
2977
|
"""
|
2978
|
+
|
2844
2979
|
def get_type(self) -> str:
|
2845
2980
|
"""
|
2846
2981
|
Get the type of the endpoint.
|
2847
2982
|
|
2848
2983
|
Returns:
|
2849
|
-
str: The type of the endpoint, "
|
2984
|
+
str: The type of the endpoint, "guidance".
|
2850
2985
|
"""
|
2851
2986
|
return "guidance"
|
2852
2987
|
|
@@ -2883,6 +3018,7 @@ class PromptsEndpoint(ComponentEndpoint, ClientEndpoint, OrganizationOwned):
|
|
2883
3018
|
It provides methods to get the type, page class, and instance class of the endpoint,
|
2884
3019
|
as well as to deploy an extension pack from a URL.
|
2885
3020
|
"""
|
3021
|
+
|
2886
3022
|
def get_type(self) -> str:
|
2887
3023
|
"""
|
2888
3024
|
Get the type of the endpoint.
|
@@ -4973,10 +5109,28 @@ class DataStoreEndpoint(StoreEndpoint):
|
|
4973
5109
|
|
4974
5110
|
|
4975
5111
|
class DocumentStoreEndpoint(StoreEndpoint):
|
4976
|
-
"""Represents a document store that can be used to store files and their related document representations."""
|
4977
|
-
|
4978
5112
|
"""Represents a document store that can be used to store files and then their related document representations"""
|
4979
5113
|
|
5114
|
+
def query_by_embedding(self, embedding: list[float], threshold: float, limit: int):
|
5115
|
+
"""
|
5116
|
+
Query the document store by an embedding.
|
5117
|
+
|
5118
|
+
Args:
|
5119
|
+
embedding (list[float]): The embedding to query by.
|
5120
|
+
threshold (int): The threshold to use for the query.
|
5121
|
+
limit (int): The limit of the query.
|
5122
|
+
|
5123
|
+
Returns:
|
5124
|
+
list[DocumentEmbedding]: a list of document embeddings
|
5125
|
+
"""
|
5126
|
+
url = "/api/embeddings/query"
|
5127
|
+
embedding_query = {"embedding": embedding, "threshold": threshold, "limit": limit, "storeRef": self.ref}
|
5128
|
+
response = self.client.post(url, body=embedding_query)
|
5129
|
+
process_response(response)
|
5130
|
+
|
5131
|
+
# We get a list of the document embeddings
|
5132
|
+
return [DocumentEmbedding.model_validate(embedding) for embedding in response.json()]
|
5133
|
+
|
4980
5134
|
def delete_by_path(self, object_path: str):
|
4981
5135
|
"""
|
4982
5136
|
Delete the content stored in the store at the given path.
|
@@ -5271,6 +5425,8 @@ class DocumentStoreEndpoint(StoreEndpoint):
|
|
5271
5425
|
count += 1
|
5272
5426
|
if limit and count >= limit:
|
5273
5427
|
break
|
5428
|
+
if limit and count >= limit:
|
5429
|
+
break
|
5274
5430
|
page += 1
|
5275
5431
|
|
5276
5432
|
def filter(
|
@@ -5357,6 +5513,7 @@ class DocumentStoreEndpoint(StoreEndpoint):
|
|
5357
5513
|
f"api/stores/{self.ref.replace(':', '/')}/fs",
|
5358
5514
|
params={"path": path, "meta": True},
|
5359
5515
|
)
|
5516
|
+
process_response(get_response)
|
5360
5517
|
return DocumentFamilyEndpoint.model_validate(get_response.json()).set_client(
|
5361
5518
|
self.client
|
5362
5519
|
)
|
@@ -5448,6 +5605,7 @@ class ModelStoreEndpoint(DocumentStoreEndpoint):
|
|
5448
5605
|
response = self.client.get(
|
5449
5606
|
f"/api/stores/{self.ref.replace(':', '/')}/trainings/{training_id}/content"
|
5450
5607
|
)
|
5608
|
+
process_response(response)
|
5451
5609
|
from zipfile import ZipFile
|
5452
5610
|
from io import BytesIO
|
5453
5611
|
|
@@ -5467,6 +5625,7 @@ class ModelStoreEndpoint(DocumentStoreEndpoint):
|
|
5467
5625
|
response = self.client.get(
|
5468
5626
|
f"/api/stores/{self.ref.replace(':', '/')}/implementation"
|
5469
5627
|
)
|
5628
|
+
process_response(response)
|
5470
5629
|
from zipfile import ZipFile
|
5471
5630
|
from io import BytesIO
|
5472
5631
|
|
@@ -5652,6 +5811,11 @@ class ModelStoreEndpoint(DocumentStoreEndpoint):
|
|
5652
5811
|
zipf.write(path_hit, relative_path)
|
5653
5812
|
num_hits += 1
|
5654
5813
|
|
5814
|
+
if num_hits == 0:
|
5815
|
+
print(
|
5816
|
+
f"No files found for implementation in {metadata.base_dir} with {metadata.contents}"
|
5817
|
+
)
|
5818
|
+
|
5655
5819
|
return num_hits
|
5656
5820
|
|
5657
5821
|
def upload_contents(self, metadata: ModelContentMetadata, dry_run=False):
|
@@ -5669,10 +5833,11 @@ class ModelStoreEndpoint(DocumentStoreEndpoint):
|
|
5669
5833
|
num_hits = self.build_implementation_zip(metadata)
|
5670
5834
|
if num_hits > 0 and not dry_run:
|
5671
5835
|
with open("implementation.zip", "rb") as zip_content:
|
5672
|
-
self.client.post(
|
5836
|
+
response = self.client.post(
|
5673
5837
|
f"/api/stores/{self.ref.replace(':', '/')}/implementation",
|
5674
5838
|
files={"implementation": zip_content},
|
5675
5839
|
)
|
5840
|
+
process_response(response)
|
5676
5841
|
results.append(f"{num_hits} files packaged and deployed to {self.ref}")
|
5677
5842
|
if not metadata.keep_zip:
|
5678
5843
|
Path("implementation.zip").unlink()
|
@@ -5754,6 +5919,8 @@ def process_response(response) -> requests.Response:
|
|
5754
5919
|
raise Exception(f"Unauthorized ({response.text})")
|
5755
5920
|
if response.status_code == 404:
|
5756
5921
|
raise Exception(f"Not found ({response.text})")
|
5922
|
+
if response.status_code in [301, 302]:
|
5923
|
+
raise Exception(f"Redirected ({response.text})")
|
5757
5924
|
if response.status_code == 405:
|
5758
5925
|
raise Exception("Method not allowed")
|
5759
5926
|
if response.status_code == 500:
|
@@ -5769,11 +5936,6 @@ def process_response(response) -> requests.Response:
|
|
5769
5936
|
|
5770
5937
|
return response
|
5771
5938
|
|
5772
|
-
#
|
5773
|
-
# The Kodexa Client is the way that brings everything together
|
5774
|
-
#
|
5775
|
-
#
|
5776
|
-
|
5777
5939
|
|
5778
5940
|
OBJECT_TYPES = {
|
5779
5941
|
"extensionPacks": {
|
@@ -5829,7 +5991,7 @@ OBJECT_TYPES = {
|
|
5829
5991
|
"name": "guidance",
|
5830
5992
|
"plural": "guidance",
|
5831
5993
|
"type": GuidanceSetEndpoint,
|
5832
|
-
"endpoint":
|
5994
|
+
"endpoint": GuidanceSetsEndpoint,
|
5833
5995
|
},
|
5834
5996
|
"modelRuntimes": {
|
5835
5997
|
"name": "modelRuntime",
|
@@ -5969,9 +6131,10 @@ class ExtractionEngineEndpoint:
|
|
5969
6131
|
"""
|
5970
6132
|
response = self.client.post(
|
5971
6133
|
"/api/extractionEngine/extract",
|
5972
|
-
data={"taxonomyJson": taxonomy.model_dump_json()},
|
6134
|
+
data={"taxonomyJson": taxonomy.model_dump_json(by_alias=True)},
|
5973
6135
|
files={"document": document.to_kddb()},
|
5974
6136
|
)
|
6137
|
+
print(response.json())
|
5975
6138
|
return [
|
5976
6139
|
DataObject.model_validate(data_object) for data_object in response.json()
|
5977
6140
|
]
|
@@ -5992,7 +6155,7 @@ class ExtractionEngineEndpoint:
|
|
5992
6155
|
response = self.client.post(
|
5993
6156
|
"/api/extractionEngine/extract",
|
5994
6157
|
params="full",
|
5995
|
-
data={"taxonomyJson": taxonomy.model_dump_json()},
|
6158
|
+
data={"taxonomyJson": taxonomy.model_dump_json(by_alias=True)},
|
5996
6159
|
files={"document": document.to_kddb()},
|
5997
6160
|
)
|
5998
6161
|
return {
|
@@ -6023,7 +6186,7 @@ class ExtractionEngineEndpoint:
|
|
6023
6186
|
response = self.client.post(
|
6024
6187
|
"/api/extractionEngine/extract",
|
6025
6188
|
params={"format": format},
|
6026
|
-
data={"taxonomyJson": taxonomy.model_dump_json()},
|
6189
|
+
data={"taxonomyJson": taxonomy.model_dump_json(by_alias=True)},
|
6027
6190
|
files={"document": document.to_kddb()},
|
6028
6191
|
)
|
6029
6192
|
return response.text
|
@@ -6046,7 +6209,7 @@ class KodexaClient:
|
|
6046
6209
|
messages (MessagesEndpoint): An endpoint for messages.
|
6047
6210
|
"""
|
6048
6211
|
|
6049
|
-
def __init__(self, url=None, access_token=None, profile=
|
6212
|
+
def __init__(self, url=None, access_token=None, profile=None):
|
6050
6213
|
from kodexa import KodexaPlatform
|
6051
6214
|
|
6052
6215
|
self.base_url = url if url is not None else KodexaPlatform.get_url(profile)
|
@@ -6064,16 +6227,18 @@ class KodexaClient:
|
|
6064
6227
|
self.channels = ChannelsEndpoint(self)
|
6065
6228
|
self.assistants = AssistantsEndpoint(self)
|
6066
6229
|
self.messages = MessagesEndpoint(self)
|
6230
|
+
from kodexa.model.entities.product import ProductsEndpoint
|
6231
|
+
self.products = ProductsEndpoint(self)
|
6232
|
+
self.guidance_sets = GuidanceSetsEndpoint(self)
|
6067
6233
|
|
6068
6234
|
@staticmethod
|
6069
|
-
def login(url,
|
6235
|
+
def login(url, token):
|
6070
6236
|
"""
|
6071
6237
|
A static method to login to the Kodexa platform.
|
6072
6238
|
|
6073
6239
|
Args:
|
6074
6240
|
url (str): The URL for the Kodexa platform.
|
6075
|
-
|
6076
|
-
password (str): The password for the user.
|
6241
|
+
token (str): The email for the user.
|
6077
6242
|
|
6078
6243
|
Returns:
|
6079
6244
|
KodexaClient: A KodexaClient instance.
|
@@ -6084,9 +6249,10 @@ class KodexaClient:
|
|
6084
6249
|
from requests.auth import HTTPBasicAuth
|
6085
6250
|
|
6086
6251
|
obj_response = requests.get(
|
6087
|
-
f"{url}/api/account/me
|
6088
|
-
|
6089
|
-
|
6252
|
+
f"{url}/api/account/me",
|
6253
|
+
headers={"content-type": "application/json",
|
6254
|
+
"x-access-token": token,
|
6255
|
+
"cf-access-token": os.environ.get("CF_TOKEN", "")}
|
6090
6256
|
)
|
6091
6257
|
if obj_response.status_code == 200:
|
6092
6258
|
return KodexaClient(url, obj_response.text)
|
@@ -6218,6 +6384,7 @@ class KodexaClient:
|
|
6218
6384
|
params=params,
|
6219
6385
|
headers={
|
6220
6386
|
"x-access-token": self.access_token,
|
6387
|
+
"cf-access-token": os.environ.get("CF_TOKEN", ""),
|
6221
6388
|
"content-type": "application/json",
|
6222
6389
|
},
|
6223
6390
|
)
|
@@ -6244,7 +6411,9 @@ class KodexaClient:
|
|
6244
6411
|
params=params,
|
6245
6412
|
headers={
|
6246
6413
|
"x-access-token": self.access_token,
|
6414
|
+
"cf-access-token": os.environ.get("CF_TOKEN", ""),
|
6247
6415
|
"content-type": "application/json",
|
6416
|
+
"X-Requested-With": "XMLHttpRequest",
|
6248
6417
|
}
|
6249
6418
|
)
|
6250
6419
|
|
@@ -6266,7 +6435,10 @@ class KodexaClient:
|
|
6266
6435
|
Returns:
|
6267
6436
|
requests.Response: The response from the server.
|
6268
6437
|
"""
|
6269
|
-
headers = {
|
6438
|
+
headers = {
|
6439
|
+
"x-access-token": self.access_token,
|
6440
|
+
"X-Requested-With": "XMLHttpRequest",
|
6441
|
+
"cf-access-token": os.environ.get("CF_TOKEN", "")}
|
6270
6442
|
if files is None:
|
6271
6443
|
headers["content-type"] = "application/json"
|
6272
6444
|
|
@@ -6296,7 +6468,9 @@ class KodexaClient:
|
|
6296
6468
|
Returns:
|
6297
6469
|
requests.Response: The response from the server.
|
6298
6470
|
"""
|
6299
|
-
headers = {"x-access-token": self.access_token
|
6471
|
+
headers = {"x-access-token": self.access_token,
|
6472
|
+
"cf-access-token": os.environ.get("CF_TOKEN", ""),
|
6473
|
+
"X-Requested-With": "XMLHttpRequest"}
|
6300
6474
|
if files is None:
|
6301
6475
|
headers["content-type"] = "application/json"
|
6302
6476
|
|
@@ -6324,7 +6498,9 @@ class KodexaClient:
|
|
6324
6498
|
response = requests.delete(
|
6325
6499
|
self.get_url(url),
|
6326
6500
|
params=params,
|
6327
|
-
headers={"x-access-token": self.access_token
|
6501
|
+
headers={"x-access-token": self.access_token,
|
6502
|
+
"cf-access-token": os.environ.get("CF_TOKEN", ""),
|
6503
|
+
"X-Requested-With": "XMLHttpRequest"}
|
6328
6504
|
)
|
6329
6505
|
return process_response(response)
|
6330
6506
|
|
@@ -6440,6 +6616,18 @@ class KodexaClient:
|
|
6440
6616
|
)
|
6441
6617
|
)
|
6442
6618
|
|
6619
|
+
for guidance in project.guidance.list():
|
6620
|
+
guidance_file = os.path.join(
|
6621
|
+
project_export_dir, f"guidance-{guidance.slug}-{guidance.version}.json"
|
6622
|
+
)
|
6623
|
+
with open(guidance_file, "w") as f:
|
6624
|
+
f.write(
|
6625
|
+
json.dumps(
|
6626
|
+
guidance.model_dump(mode="json", by_alias=True), indent=4
|
6627
|
+
)
|
6628
|
+
)
|
6629
|
+
|
6630
|
+
|
6443
6631
|
def import_project(self, organization: OrganizationEndpoint, import_path: str):
|
6444
6632
|
"""
|
6445
6633
|
A method to import a project.
|
@@ -6533,6 +6721,13 @@ class KodexaClient:
|
|
6533
6721
|
taxonomy.ref = None
|
6534
6722
|
taxonomies.append(organization.taxonomies.create(taxonomy))
|
6535
6723
|
|
6724
|
+
for guidance_file in glob.glob(os.path.join(import_path, "guidance-*.json")):
|
6725
|
+
with open(guidance_file, "r") as f:
|
6726
|
+
guidance = GuidanceSetEndpoint.model_validate(json.load(f))
|
6727
|
+
guidance.org_slug = None
|
6728
|
+
guidance.ref = None
|
6729
|
+
organization.guidance.create(guidance)
|
6730
|
+
|
6536
6731
|
import time
|
6537
6732
|
|
6538
6733
|
time.sleep(4)
|
@@ -6603,6 +6798,8 @@ class KodexaClient:
|
|
6603
6798
|
|
6604
6799
|
raise Exception("A store must have a storeType")
|
6605
6800
|
|
6801
|
+
from kodexa.model.entities.product import ProductEndpoint
|
6802
|
+
from kodexa.model.entities.product_subscription import ProductSubscriptionEndpoint
|
6606
6803
|
known_components = {
|
6607
6804
|
"taxonomy": TaxonomyEndpoint,
|
6608
6805
|
"pipeline": PipelineEndpoint,
|
@@ -6626,6 +6823,8 @@ class KodexaClient:
|
|
6626
6823
|
"prompt": PromptEndpoint,
|
6627
6824
|
"guidance": GuidanceSetEndpoint,
|
6628
6825
|
"channel": ChannelEndpoint,
|
6826
|
+
"product": ProductEndpoint,
|
6827
|
+
"productSubscription": ProductSubscriptionEndpoint,
|
6629
6828
|
}
|
6630
6829
|
|
6631
6830
|
if component_type in known_components:
|