kodexa 7.0.1a8003211616__py3-none-any.whl → 7.0.1a9194120328__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 +274 -39
- 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.1a9194120328.dist-info}/METADATA +4 -15
- {kodexa-7.0.1a8003211616.dist-info → kodexa-7.0.1a9194120328.dist-info}/RECORD +15 -12
- {kodexa-7.0.1a8003211616.dist-info → kodexa-7.0.1a9194120328.dist-info}/LICENSE +0 -0
- {kodexa-7.0.1a8003211616.dist-info → kodexa-7.0.1a9194120328.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 ProjectGuidanceEndpoint(ProjectResourceEndpoint):
|
2155
|
+
|
2156
|
+
def get_type(self) -> str:
|
2157
|
+
return "guidance"
|
2158
|
+
|
2159
|
+
def get_instance_class(self, object_dict=None):
|
2160
|
+
return GuidanceSetEndpoint
|
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["GuidanceSetEndpoint"] = 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 ProjectGuidanceEndpoint().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,43 @@ class ProjectEndpoint(EntityEndpoint, Project):
|
|
2450
2582
|
return [ProjectTag.model_validate(tag) for tag in response.json()]
|
2451
2583
|
|
2452
2584
|
|
2585
|
+
class GuidanceSetsEndpoint(EntitiesEndpoint):
|
2586
|
+
"""Represents a message endpoint"""
|
2587
|
+
|
2588
|
+
def get_type(self) -> str:
|
2589
|
+
"""
|
2590
|
+
Get the type of the endpoint.
|
2591
|
+
|
2592
|
+
Returns:
|
2593
|
+
str: The type of the endpoint, in this case "guidance".
|
2594
|
+
"""
|
2595
|
+
return "guidance"
|
2596
|
+
|
2597
|
+
def get_instance_class(self, object_dict=None):
|
2598
|
+
"""
|
2599
|
+
Get the instance class of the endpoint.
|
2600
|
+
|
2601
|
+
Args:
|
2602
|
+
object_dict (dict, optional): An optional dictionary object. Defaults to None.
|
2603
|
+
|
2604
|
+
Returns:
|
2605
|
+
GuidanceSetEndpoint: The instance class of the endpoint.
|
2606
|
+
"""
|
2607
|
+
return GuidanceSetEndpoint
|
2608
|
+
|
2609
|
+
def get_page_class(self, object_dict=None):
|
2610
|
+
"""
|
2611
|
+
Get the page class of the endpoint.
|
2612
|
+
|
2613
|
+
Args:
|
2614
|
+
object_dict (dict, optional): An optional dictionary object. Defaults to None.
|
2615
|
+
|
2616
|
+
Returns:
|
2617
|
+
PageGuidanceSetEndpoint: The page class of the endpoint.
|
2618
|
+
"""
|
2619
|
+
return PageGuidanceSetEndpoint
|
2620
|
+
|
2621
|
+
|
2453
2622
|
class MessagesEndpoint(EntitiesEndpoint):
|
2454
2623
|
"""Represents a message endpoint"""
|
2455
2624
|
|
@@ -2652,12 +2821,13 @@ class ProjectsEndpoint(EntitiesEndpoint):
|
|
2652
2821
|
"""
|
2653
2822
|
return PageProjectEndpoint
|
2654
2823
|
|
2655
|
-
def find_by_name(self, project_name: str) -> Optional[ProjectEndpoint]:
|
2824
|
+
def find_by_name(self, project_name: str, organization: Optional[Organization] = None) -> Optional[ProjectEndpoint]:
|
2656
2825
|
"""
|
2657
2826
|
Find a project by name.
|
2658
2827
|
|
2659
2828
|
Args:
|
2660
2829
|
project_name (str): The name of the project to find.
|
2830
|
+
organization (Organization, optional): The organization to search in. Defaults to None.
|
2661
2831
|
|
2662
2832
|
Returns:
|
2663
2833
|
Optional[ProjectEndpoint]: The project endpoint if found, None otherwise.
|
@@ -2665,8 +2835,8 @@ class ProjectsEndpoint(EntitiesEndpoint):
|
|
2665
2835
|
|
2666
2836
|
url = f"/api/{self.get_type()}"
|
2667
2837
|
filters = {"filter": [f"name: '{project_name}'"]}
|
2668
|
-
if
|
2669
|
-
filters["filter"].append(f"organization.id: '{
|
2838
|
+
if organization is not None:
|
2839
|
+
filters["filter"].append(f"organization.id: '{organization.id}'")
|
2670
2840
|
get_response = self.client.get(url, params=filters)
|
2671
2841
|
if len(get_response.json()["content"]) > 0:
|
2672
2842
|
return ProjectEndpoint.model_validate(
|
@@ -2734,7 +2904,7 @@ class ProjectsEndpoint(EntitiesEndpoint):
|
|
2734
2904
|
if self.organization is not None:
|
2735
2905
|
params["filter"].append(f"organization.id: '{self.organization.id}'")
|
2736
2906
|
|
2737
|
-
get_response = self.client.get(f"/api/{self.get_type()}
|
2907
|
+
get_response = self.client.get(f"/api/{self.get_type()}", params=params)
|
2738
2908
|
|
2739
2909
|
return PageProjectEndpoint.model_validate(get_response.json()).set_client(
|
2740
2910
|
self.client
|
@@ -2837,16 +3007,17 @@ class GuidanceEndpoint(ComponentEndpoint, ClientEndpoint, OrganizationOwned):
|
|
2837
3007
|
"""
|
2838
3008
|
Represents a guidance endpoint.
|
2839
3009
|
|
2840
|
-
This class is used to interact with the
|
3010
|
+
This class is used to interact with the guidance endpoint of the API.
|
2841
3011
|
It provides methods to get the type, page class, and instance class of the endpoint,
|
2842
3012
|
as well as to deploy an extension pack from a URL.
|
2843
3013
|
"""
|
3014
|
+
|
2844
3015
|
def get_type(self) -> str:
|
2845
3016
|
"""
|
2846
3017
|
Get the type of the endpoint.
|
2847
3018
|
|
2848
3019
|
Returns:
|
2849
|
-
str: The type of the endpoint, "
|
3020
|
+
str: The type of the endpoint, "guidance".
|
2850
3021
|
"""
|
2851
3022
|
return "guidance"
|
2852
3023
|
|
@@ -2883,6 +3054,7 @@ class PromptsEndpoint(ComponentEndpoint, ClientEndpoint, OrganizationOwned):
|
|
2883
3054
|
It provides methods to get the type, page class, and instance class of the endpoint,
|
2884
3055
|
as well as to deploy an extension pack from a URL.
|
2885
3056
|
"""
|
3057
|
+
|
2886
3058
|
def get_type(self) -> str:
|
2887
3059
|
"""
|
2888
3060
|
Get the type of the endpoint.
|
@@ -4973,10 +5145,28 @@ class DataStoreEndpoint(StoreEndpoint):
|
|
4973
5145
|
|
4974
5146
|
|
4975
5147
|
class DocumentStoreEndpoint(StoreEndpoint):
|
4976
|
-
"""Represents a document store that can be used to store files and their related document representations."""
|
4977
|
-
|
4978
5148
|
"""Represents a document store that can be used to store files and then their related document representations"""
|
4979
5149
|
|
5150
|
+
def query_by_embedding(self, embedding: list[float], threshold: float, limit: int):
|
5151
|
+
"""
|
5152
|
+
Query the document store by an embedding.
|
5153
|
+
|
5154
|
+
Args:
|
5155
|
+
embedding (list[float]): The embedding to query by.
|
5156
|
+
threshold (int): The threshold to use for the query.
|
5157
|
+
limit (int): The limit of the query.
|
5158
|
+
|
5159
|
+
Returns:
|
5160
|
+
list[DocumentEmbedding]: a list of document embeddings
|
5161
|
+
"""
|
5162
|
+
url = "/api/embeddings/query"
|
5163
|
+
embedding_query = {"embedding": embedding, "threshold": threshold, "limit": limit, "storeRef": self.ref}
|
5164
|
+
response = self.client.post(url, body=embedding_query)
|
5165
|
+
process_response(response)
|
5166
|
+
|
5167
|
+
# We get a list of the document embeddings
|
5168
|
+
return [DocumentEmbedding.model_validate(embedding) for embedding in response.json()]
|
5169
|
+
|
4980
5170
|
def delete_by_path(self, object_path: str):
|
4981
5171
|
"""
|
4982
5172
|
Delete the content stored in the store at the given path.
|
@@ -5271,6 +5461,8 @@ class DocumentStoreEndpoint(StoreEndpoint):
|
|
5271
5461
|
count += 1
|
5272
5462
|
if limit and count >= limit:
|
5273
5463
|
break
|
5464
|
+
if limit and count >= limit:
|
5465
|
+
break
|
5274
5466
|
page += 1
|
5275
5467
|
|
5276
5468
|
def filter(
|
@@ -5357,6 +5549,7 @@ class DocumentStoreEndpoint(StoreEndpoint):
|
|
5357
5549
|
f"api/stores/{self.ref.replace(':', '/')}/fs",
|
5358
5550
|
params={"path": path, "meta": True},
|
5359
5551
|
)
|
5552
|
+
process_response(get_response)
|
5360
5553
|
return DocumentFamilyEndpoint.model_validate(get_response.json()).set_client(
|
5361
5554
|
self.client
|
5362
5555
|
)
|
@@ -5448,6 +5641,7 @@ class ModelStoreEndpoint(DocumentStoreEndpoint):
|
|
5448
5641
|
response = self.client.get(
|
5449
5642
|
f"/api/stores/{self.ref.replace(':', '/')}/trainings/{training_id}/content"
|
5450
5643
|
)
|
5644
|
+
process_response(response)
|
5451
5645
|
from zipfile import ZipFile
|
5452
5646
|
from io import BytesIO
|
5453
5647
|
|
@@ -5467,6 +5661,7 @@ class ModelStoreEndpoint(DocumentStoreEndpoint):
|
|
5467
5661
|
response = self.client.get(
|
5468
5662
|
f"/api/stores/{self.ref.replace(':', '/')}/implementation"
|
5469
5663
|
)
|
5664
|
+
process_response(response)
|
5470
5665
|
from zipfile import ZipFile
|
5471
5666
|
from io import BytesIO
|
5472
5667
|
|
@@ -5652,6 +5847,11 @@ class ModelStoreEndpoint(DocumentStoreEndpoint):
|
|
5652
5847
|
zipf.write(path_hit, relative_path)
|
5653
5848
|
num_hits += 1
|
5654
5849
|
|
5850
|
+
if num_hits == 0:
|
5851
|
+
print(
|
5852
|
+
f"No files found for implementation in {metadata.base_dir} with {metadata.contents}"
|
5853
|
+
)
|
5854
|
+
|
5655
5855
|
return num_hits
|
5656
5856
|
|
5657
5857
|
def upload_contents(self, metadata: ModelContentMetadata, dry_run=False):
|
@@ -5669,10 +5869,11 @@ class ModelStoreEndpoint(DocumentStoreEndpoint):
|
|
5669
5869
|
num_hits = self.build_implementation_zip(metadata)
|
5670
5870
|
if num_hits > 0 and not dry_run:
|
5671
5871
|
with open("implementation.zip", "rb") as zip_content:
|
5672
|
-
self.client.post(
|
5872
|
+
response = self.client.post(
|
5673
5873
|
f"/api/stores/{self.ref.replace(':', '/')}/implementation",
|
5674
5874
|
files={"implementation": zip_content},
|
5675
5875
|
)
|
5876
|
+
process_response(response)
|
5676
5877
|
results.append(f"{num_hits} files packaged and deployed to {self.ref}")
|
5677
5878
|
if not metadata.keep_zip:
|
5678
5879
|
Path("implementation.zip").unlink()
|
@@ -5754,6 +5955,8 @@ def process_response(response) -> requests.Response:
|
|
5754
5955
|
raise Exception(f"Unauthorized ({response.text})")
|
5755
5956
|
if response.status_code == 404:
|
5756
5957
|
raise Exception(f"Not found ({response.text})")
|
5958
|
+
if response.status_code in [301, 302]:
|
5959
|
+
raise Exception(f"Redirected ({response.text})")
|
5757
5960
|
if response.status_code == 405:
|
5758
5961
|
raise Exception("Method not allowed")
|
5759
5962
|
if response.status_code == 500:
|
@@ -5769,11 +5972,6 @@ def process_response(response) -> requests.Response:
|
|
5769
5972
|
|
5770
5973
|
return response
|
5771
5974
|
|
5772
|
-
#
|
5773
|
-
# The Kodexa Client is the way that brings everything together
|
5774
|
-
#
|
5775
|
-
#
|
5776
|
-
|
5777
5975
|
|
5778
5976
|
OBJECT_TYPES = {
|
5779
5977
|
"extensionPacks": {
|
@@ -5969,9 +6167,10 @@ class ExtractionEngineEndpoint:
|
|
5969
6167
|
"""
|
5970
6168
|
response = self.client.post(
|
5971
6169
|
"/api/extractionEngine/extract",
|
5972
|
-
data={"taxonomyJson": taxonomy.model_dump_json()},
|
6170
|
+
data={"taxonomyJson": taxonomy.model_dump_json(by_alias=True)},
|
5973
6171
|
files={"document": document.to_kddb()},
|
5974
6172
|
)
|
6173
|
+
print(response.json())
|
5975
6174
|
return [
|
5976
6175
|
DataObject.model_validate(data_object) for data_object in response.json()
|
5977
6176
|
]
|
@@ -5992,7 +6191,7 @@ class ExtractionEngineEndpoint:
|
|
5992
6191
|
response = self.client.post(
|
5993
6192
|
"/api/extractionEngine/extract",
|
5994
6193
|
params="full",
|
5995
|
-
data={"taxonomyJson": taxonomy.model_dump_json()},
|
6194
|
+
data={"taxonomyJson": taxonomy.model_dump_json(by_alias=True)},
|
5996
6195
|
files={"document": document.to_kddb()},
|
5997
6196
|
)
|
5998
6197
|
return {
|
@@ -6023,7 +6222,7 @@ class ExtractionEngineEndpoint:
|
|
6023
6222
|
response = self.client.post(
|
6024
6223
|
"/api/extractionEngine/extract",
|
6025
6224
|
params={"format": format},
|
6026
|
-
data={"taxonomyJson": taxonomy.model_dump_json()},
|
6225
|
+
data={"taxonomyJson": taxonomy.model_dump_json(by_alias=True)},
|
6027
6226
|
files={"document": document.to_kddb()},
|
6028
6227
|
)
|
6029
6228
|
return response.text
|
@@ -6046,7 +6245,7 @@ class KodexaClient:
|
|
6046
6245
|
messages (MessagesEndpoint): An endpoint for messages.
|
6047
6246
|
"""
|
6048
6247
|
|
6049
|
-
def __init__(self, url=None, access_token=None, profile=
|
6248
|
+
def __init__(self, url=None, access_token=None, profile=None):
|
6050
6249
|
from kodexa import KodexaPlatform
|
6051
6250
|
|
6052
6251
|
self.base_url = url if url is not None else KodexaPlatform.get_url(profile)
|
@@ -6064,16 +6263,18 @@ class KodexaClient:
|
|
6064
6263
|
self.channels = ChannelsEndpoint(self)
|
6065
6264
|
self.assistants = AssistantsEndpoint(self)
|
6066
6265
|
self.messages = MessagesEndpoint(self)
|
6266
|
+
from kodexa.model.entities.product import ProductsEndpoint
|
6267
|
+
self.products = ProductsEndpoint(self)
|
6268
|
+
self.guidance_sets = GuidanceSetsEndpoint(self)
|
6067
6269
|
|
6068
6270
|
@staticmethod
|
6069
|
-
def login(url,
|
6271
|
+
def login(url, token):
|
6070
6272
|
"""
|
6071
6273
|
A static method to login to the Kodexa platform.
|
6072
6274
|
|
6073
6275
|
Args:
|
6074
6276
|
url (str): The URL for the Kodexa platform.
|
6075
|
-
|
6076
|
-
password (str): The password for the user.
|
6277
|
+
token (str): The email for the user.
|
6077
6278
|
|
6078
6279
|
Returns:
|
6079
6280
|
KodexaClient: A KodexaClient instance.
|
@@ -6084,9 +6285,10 @@ class KodexaClient:
|
|
6084
6285
|
from requests.auth import HTTPBasicAuth
|
6085
6286
|
|
6086
6287
|
obj_response = requests.get(
|
6087
|
-
f"{url}/api/account/me
|
6088
|
-
|
6089
|
-
|
6288
|
+
f"{url}/api/account/me",
|
6289
|
+
headers={"content-type": "application/json",
|
6290
|
+
"x-access-token": token,
|
6291
|
+
"cf-access-token": os.environ.get("CF_TOKEN", "")}
|
6090
6292
|
)
|
6091
6293
|
if obj_response.status_code == 200:
|
6092
6294
|
return KodexaClient(url, obj_response.text)
|
@@ -6218,6 +6420,7 @@ class KodexaClient:
|
|
6218
6420
|
params=params,
|
6219
6421
|
headers={
|
6220
6422
|
"x-access-token": self.access_token,
|
6423
|
+
"cf-access-token": os.environ.get("CF_TOKEN", ""),
|
6221
6424
|
"content-type": "application/json",
|
6222
6425
|
},
|
6223
6426
|
)
|
@@ -6244,7 +6447,9 @@ class KodexaClient:
|
|
6244
6447
|
params=params,
|
6245
6448
|
headers={
|
6246
6449
|
"x-access-token": self.access_token,
|
6450
|
+
"cf-access-token": os.environ.get("CF_TOKEN", ""),
|
6247
6451
|
"content-type": "application/json",
|
6452
|
+
"X-Requested-With": "XMLHttpRequest",
|
6248
6453
|
}
|
6249
6454
|
)
|
6250
6455
|
|
@@ -6266,7 +6471,10 @@ class KodexaClient:
|
|
6266
6471
|
Returns:
|
6267
6472
|
requests.Response: The response from the server.
|
6268
6473
|
"""
|
6269
|
-
headers = {
|
6474
|
+
headers = {
|
6475
|
+
"x-access-token": self.access_token,
|
6476
|
+
"X-Requested-With": "XMLHttpRequest",
|
6477
|
+
"cf-access-token": os.environ.get("CF_TOKEN", "")}
|
6270
6478
|
if files is None:
|
6271
6479
|
headers["content-type"] = "application/json"
|
6272
6480
|
|
@@ -6296,7 +6504,9 @@ class KodexaClient:
|
|
6296
6504
|
Returns:
|
6297
6505
|
requests.Response: The response from the server.
|
6298
6506
|
"""
|
6299
|
-
headers = {"x-access-token": self.access_token
|
6507
|
+
headers = {"x-access-token": self.access_token,
|
6508
|
+
"cf-access-token": os.environ.get("CF_TOKEN", ""),
|
6509
|
+
"X-Requested-With": "XMLHttpRequest"}
|
6300
6510
|
if files is None:
|
6301
6511
|
headers["content-type"] = "application/json"
|
6302
6512
|
|
@@ -6324,7 +6534,9 @@ class KodexaClient:
|
|
6324
6534
|
response = requests.delete(
|
6325
6535
|
self.get_url(url),
|
6326
6536
|
params=params,
|
6327
|
-
headers={"x-access-token": self.access_token
|
6537
|
+
headers={"x-access-token": self.access_token,
|
6538
|
+
"cf-access-token": os.environ.get("CF_TOKEN", ""),
|
6539
|
+
"X-Requested-With": "XMLHttpRequest"}
|
6328
6540
|
)
|
6329
6541
|
return process_response(response)
|
6330
6542
|
|
@@ -6440,6 +6652,18 @@ class KodexaClient:
|
|
6440
6652
|
)
|
6441
6653
|
)
|
6442
6654
|
|
6655
|
+
for guidance in project.guidance.list():
|
6656
|
+
guidance_file = os.path.join(
|
6657
|
+
project_export_dir, f"guidance-{guidance.slug}-{guidance.version}.json"
|
6658
|
+
)
|
6659
|
+
with open(guidance_file, "w") as f:
|
6660
|
+
f.write(
|
6661
|
+
json.dumps(
|
6662
|
+
guidance.model_dump(mode="json", by_alias=True), indent=4
|
6663
|
+
)
|
6664
|
+
)
|
6665
|
+
|
6666
|
+
|
6443
6667
|
def import_project(self, organization: OrganizationEndpoint, import_path: str):
|
6444
6668
|
"""
|
6445
6669
|
A method to import a project.
|
@@ -6533,6 +6757,13 @@ class KodexaClient:
|
|
6533
6757
|
taxonomy.ref = None
|
6534
6758
|
taxonomies.append(organization.taxonomies.create(taxonomy))
|
6535
6759
|
|
6760
|
+
for guidance_file in glob.glob(os.path.join(import_path, "guidance-*.json")):
|
6761
|
+
with open(guidance_file, "r") as f:
|
6762
|
+
guidance = GuidanceSetEndpoint.model_validate(json.load(f))
|
6763
|
+
guidance.org_slug = None
|
6764
|
+
guidance.ref = None
|
6765
|
+
organization.guidance.create(guidance)
|
6766
|
+
|
6536
6767
|
import time
|
6537
6768
|
|
6538
6769
|
time.sleep(4)
|
@@ -6603,6 +6834,8 @@ class KodexaClient:
|
|
6603
6834
|
|
6604
6835
|
raise Exception("A store must have a storeType")
|
6605
6836
|
|
6837
|
+
from kodexa.model.entities.product import ProductEndpoint
|
6838
|
+
from kodexa.model.entities.product_subscription import ProductSubscriptionEndpoint
|
6606
6839
|
known_components = {
|
6607
6840
|
"taxonomy": TaxonomyEndpoint,
|
6608
6841
|
"pipeline": PipelineEndpoint,
|
@@ -6626,6 +6859,8 @@ class KodexaClient:
|
|
6626
6859
|
"prompt": PromptEndpoint,
|
6627
6860
|
"guidance": GuidanceSetEndpoint,
|
6628
6861
|
"channel": ChannelEndpoint,
|
6862
|
+
"product": ProductEndpoint,
|
6863
|
+
"productSubscription": ProductSubscriptionEndpoint,
|
6629
6864
|
}
|
6630
6865
|
|
6631
6866
|
if component_type in known_components:
|