processcube-client 4.0.0a1__tar.gz
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.
- processcube_client-4.0.0a1/PKG-INFO +24 -0
- processcube_client-4.0.0a1/README.md +7 -0
- processcube_client-4.0.0a1/processcube_client/__init__.py +22 -0
- processcube_client-4.0.0a1/processcube_client/app_info/__init__.py +1 -0
- processcube_client-4.0.0a1/processcube_client/app_info/app_info_client.py +66 -0
- processcube_client-4.0.0a1/processcube_client/client_factory.py +40 -0
- processcube_client-4.0.0a1/processcube_client/core/__init__.py +2 -0
- processcube_client-4.0.0a1/processcube_client/core/api/__init__.py +13 -0
- processcube_client-4.0.0a1/processcube_client/core/api/base_client.py +103 -0
- processcube_client-4.0.0a1/processcube_client/core/api/client.py +256 -0
- processcube_client-4.0.0a1/processcube_client/core/api/helpers/__init__.py +0 -0
- processcube_client-4.0.0a1/processcube_client/core/api/helpers/application_info.py +36 -0
- processcube_client-4.0.0a1/processcube_client/core/api/helpers/data_object_instances.py +56 -0
- processcube_client-4.0.0a1/processcube_client/core/api/helpers/empty_tasks.py +76 -0
- processcube_client-4.0.0a1/processcube_client/core/api/helpers/events.py +38 -0
- processcube_client-4.0.0a1/processcube_client/core/api/helpers/external_tasks.py +122 -0
- processcube_client-4.0.0a1/processcube_client/core/api/helpers/flow_node_instances.py +75 -0
- processcube_client-4.0.0a1/processcube_client/core/api/helpers/manual_tasks.py +76 -0
- processcube_client-4.0.0a1/processcube_client/core/api/helpers/process_definitions.py +29 -0
- processcube_client-4.0.0a1/processcube_client/core/api/helpers/process_instances.py +94 -0
- processcube_client-4.0.0a1/processcube_client/core/api/helpers/process_models.py +46 -0
- processcube_client-4.0.0a1/processcube_client/core/api/helpers/user_tasks.py +109 -0
- processcube_client-4.0.0a1/processcube_client/core/base_client.py +125 -0
- processcube_client-4.0.0a1/processcube_client/core/loop_helper.py +189 -0
- processcube_client-4.0.0a1/processcube_client/event/__init__.py +1 -0
- processcube_client-4.0.0a1/processcube_client/event/event_client.py +73 -0
- processcube_client-4.0.0a1/processcube_client/external_task/__init__.py +3 -0
- processcube_client-4.0.0a1/processcube_client/external_task/client_wrapper.py +28 -0
- processcube_client-4.0.0a1/processcube_client/external_task/external_task_client.py +164 -0
- processcube_client-4.0.0a1/processcube_client/external_task/external_task_worker.py +208 -0
- processcube_client-4.0.0a1/processcube_client/external_task/functional_error.py +17 -0
- processcube_client-4.0.0a1/processcube_client/flow_node_instance/__init__.py +1 -0
- processcube_client-4.0.0a1/processcube_client/flow_node_instance/flow_node_instance_client.py +69 -0
- processcube_client-4.0.0a1/processcube_client/notification/__init__.py +1 -0
- processcube_client-4.0.0a1/processcube_client/notification/notification_client.py +105 -0
- processcube_client-4.0.0a1/processcube_client/process_definition/__init__.py +2 -0
- processcube_client-4.0.0a1/processcube_client/process_definition/process_definition_client.py +115 -0
- processcube_client-4.0.0a1/processcube_client/process_definition/start_callback_type.py +6 -0
- processcube_client-4.0.0a1/processcube_client/process_instance/__init__.py +1 -0
- processcube_client-4.0.0a1/processcube_client/process_instance/process_instance_client.py +53 -0
- processcube_client-4.0.0a1/processcube_client/user_task/__init__.py +1 -0
- processcube_client-4.0.0a1/processcube_client/user_task/user_task_client.py +63 -0
- processcube_client-4.0.0a1/processcube_client.egg-info/PKG-INFO +24 -0
- processcube_client-4.0.0a1/processcube_client.egg-info/SOURCES.txt +54 -0
- processcube_client-4.0.0a1/processcube_client.egg-info/dependency_links.txt +1 -0
- processcube_client-4.0.0a1/processcube_client.egg-info/requires.txt +4 -0
- processcube_client-4.0.0a1/processcube_client.egg-info/top_level.txt +2 -0
- processcube_client-4.0.0a1/setup.cfg +4 -0
- processcube_client-4.0.0a1/setup.py +38 -0
- processcube_client-4.0.0a1/tests/__init__.py +0 -0
- processcube_client-4.0.0a1/tests/core/__init__.py +0 -0
- processcube_client-4.0.0a1/tests/core/test_base_client.py +33 -0
- processcube_client-4.0.0a1/tests/core/test_loop_helper.py +10 -0
- processcube_client-4.0.0a1/tests/helper_aiohttp.py +111 -0
- processcube_client-4.0.0a1/tests/process_control/__init__.py +0 -0
- processcube_client-4.0.0a1/tests/process_control/test_process_control_client.py +61 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: processcube_client
|
|
3
|
+
Version: 4.0.0a1
|
|
4
|
+
Summary: A Client for the workflow engine of the ProcessCube platform.
|
|
5
|
+
Home-page: https://github.com/5minds/processcube_client.py
|
|
6
|
+
Author: 5Minds IT-Solutions GmbH & Co. KG
|
|
7
|
+
Author-email: ProcessCube@5Minds.de
|
|
8
|
+
Keywords: workflow-engine atlas-engine client bpmn
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
Requires-Dist: aiohttp==3.8.3
|
|
14
|
+
Requires-Dist: nest-asyncio==1.5.6
|
|
15
|
+
Requires-Dist: dataclasses-json>=0.5.7
|
|
16
|
+
Requires-Dist: requests>=2.28.1
|
|
17
|
+
|
|
18
|
+
# Client zur Anbindung des ProcessCube®
|
|
19
|
+
|
|
20
|
+
Der [ProcessCube®](https://www.5minds.de/processcube/) ist ein BPMN-Engine
|
|
21
|
+
der mittels [Python](http://processcube.io/docs/engine/clients/python/)
|
|
22
|
+
angebunden werden kann. Die Beispiel sind unter [Developer-Seite](http://processcube.io/)
|
|
23
|
+
zu finden.
|
|
24
|
+
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Client zur Anbindung des ProcessCube®
|
|
2
|
+
|
|
3
|
+
Der [ProcessCube®](https://www.5minds.de/processcube/) ist ein BPMN-Engine
|
|
4
|
+
der mittels [Python](http://processcube.io/docs/engine/clients/python/)
|
|
5
|
+
angebunden werden kann. Die Beispiel sind unter [Developer-Seite](http://processcube.io/)
|
|
6
|
+
zu finden.
|
|
7
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
from .client_factory import ClientFactory
|
|
2
|
+
from .app_info import AppInfoClient
|
|
3
|
+
from .event import EventClient
|
|
4
|
+
from .external_task import ClientWrapper, ExternalTaskClient
|
|
5
|
+
from .flow_node_instance import FlowNodeInstanceClient
|
|
6
|
+
from .notification import NotificationClient
|
|
7
|
+
from .process_instance import ProcessInstanceClient
|
|
8
|
+
from .process_definition import ProcessDefinitionClient
|
|
9
|
+
from .user_task import UserTaskClient
|
|
10
|
+
|
|
11
|
+
__all__ = ['ClientFactory',
|
|
12
|
+
'AppInfoClient',
|
|
13
|
+
'EventClient',
|
|
14
|
+
'ClientWrapper',
|
|
15
|
+
'ExternalTaskClient',
|
|
16
|
+
'FlowNodeInstanceClient',
|
|
17
|
+
'NotificationClient',
|
|
18
|
+
'ProcessInstanceClient',
|
|
19
|
+
'ProcessDefinitionClient',
|
|
20
|
+
'UserTaskClient',
|
|
21
|
+
]
|
|
22
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .app_info_client import AppInfoClient
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import logging
|
|
3
|
+
|
|
4
|
+
from ..core.base_client import BaseClient
|
|
5
|
+
|
|
6
|
+
logger = logging.getLogger(__name__)
|
|
7
|
+
|
|
8
|
+
class AppInfoClient(BaseClient):
|
|
9
|
+
|
|
10
|
+
def __init__(self, url, session=None, identity=None):
|
|
11
|
+
super(AppInfoClient, self).__init__(url, session, identity)
|
|
12
|
+
|
|
13
|
+
async def __get_info(self):
|
|
14
|
+
|
|
15
|
+
url = f"/atlas_engine/api/v1/info"
|
|
16
|
+
|
|
17
|
+
result = await self.do_get(url)
|
|
18
|
+
|
|
19
|
+
return result
|
|
20
|
+
|
|
21
|
+
def get_info(self):
|
|
22
|
+
|
|
23
|
+
async def run_loop():
|
|
24
|
+
|
|
25
|
+
result = await self.__get_info()
|
|
26
|
+
|
|
27
|
+
return result
|
|
28
|
+
|
|
29
|
+
logger.info(f"Connection to atlas engine at url '{self._url}'.")
|
|
30
|
+
logger.info(f"Get info of the atlas engine.")
|
|
31
|
+
|
|
32
|
+
loop = asyncio.new_event_loop()
|
|
33
|
+
|
|
34
|
+
task = run_loop()
|
|
35
|
+
result = loop.run_until_complete(task)
|
|
36
|
+
|
|
37
|
+
loop.close()
|
|
38
|
+
|
|
39
|
+
return result
|
|
40
|
+
|
|
41
|
+
async def __get_authority(self):
|
|
42
|
+
|
|
43
|
+
url = f"/atlas_engine/api/v1/authority"
|
|
44
|
+
|
|
45
|
+
result = await self.do_get(url)
|
|
46
|
+
|
|
47
|
+
return result
|
|
48
|
+
|
|
49
|
+
def get_authority(self):
|
|
50
|
+
|
|
51
|
+
async def run_loop():
|
|
52
|
+
result = await self.__get_authority()
|
|
53
|
+
|
|
54
|
+
return result
|
|
55
|
+
|
|
56
|
+
logger.info(f"Connection to atlas engine at url '{self._url}'.")
|
|
57
|
+
logger.info(f"Get info of the authority of the atlas engine.")
|
|
58
|
+
|
|
59
|
+
loop = asyncio.new_event_loop()
|
|
60
|
+
|
|
61
|
+
task = run_loop()
|
|
62
|
+
result = loop.run_until_complete(task)
|
|
63
|
+
|
|
64
|
+
loop.close()
|
|
65
|
+
|
|
66
|
+
return result
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from processcube_client.app_info import AppInfoClient
|
|
2
|
+
from processcube_client.event import EventClient
|
|
3
|
+
from processcube_client.external_task import ClientWrapper
|
|
4
|
+
from processcube_client.flow_node_instance import FlowNodeInstanceClient
|
|
5
|
+
from processcube_client.notification import NotificationClient
|
|
6
|
+
from processcube_client.process_instance import ProcessInstanceClient
|
|
7
|
+
from processcube_client.process_definition import ProcessDefinitionClient
|
|
8
|
+
from processcube_client.user_task import UserTaskClient
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class ClientFactory:
|
|
12
|
+
|
|
13
|
+
def __init__(self):
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
def create_app_info_client(self, engine_url):
|
|
17
|
+
return AppInfoClient(engine_url)
|
|
18
|
+
|
|
19
|
+
def create_event_client(self, engine_url):
|
|
20
|
+
return EventClient(engine_url)
|
|
21
|
+
|
|
22
|
+
def create_external_task_client(self, engine_url):
|
|
23
|
+
return ClientWrapper(engine_url)
|
|
24
|
+
|
|
25
|
+
def create_flow_node_instance_client(self, engine_url):
|
|
26
|
+
return FlowNodeInstanceClient(engine_url)
|
|
27
|
+
|
|
28
|
+
def create_notification_client(self, engine_url):
|
|
29
|
+
return NotificationClient(engine_url)
|
|
30
|
+
|
|
31
|
+
def create_process_instance_client(self, engine_url):
|
|
32
|
+
return ProcessInstanceClient(engine_url)
|
|
33
|
+
|
|
34
|
+
def create_process_definition_client(self, engine_url):
|
|
35
|
+
return ProcessDefinitionClient(engine_url)
|
|
36
|
+
|
|
37
|
+
def create_user_task_client(self, engine_url):
|
|
38
|
+
return UserTaskClient(engine_url)
|
|
39
|
+
|
|
40
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from .client import Client
|
|
2
|
+
|
|
3
|
+
from .helpers.application_info import ApplicationInfo
|
|
4
|
+
from .helpers.data_object_instances import DataObjectInstanceHandler, DataObjectInstancesQuery, DataObjectInstanceResponse
|
|
5
|
+
from .helpers.empty_tasks import EmptyTaskHandler, EmptyTaskQuery, EmptyTaskResponse
|
|
6
|
+
from .helpers.events import EventsHandler, MessageTriggerRequest
|
|
7
|
+
from .helpers.process_definitions import ProcessDefinitionUploadPayload, ProcessDefinitionHandler
|
|
8
|
+
from .helpers.process_instances import ProcessInstanceHandler, ProcessInstanceQueryRequest, ProcessInstanceQueryResponse
|
|
9
|
+
from .helpers.process_models import ProcessStartResponse, ProcessStartRequest, StartCallbackType
|
|
10
|
+
from .helpers.external_tasks import FetchAndLockRequestPayload, ExternalTask, FinishExternalTaskRequestPayload
|
|
11
|
+
from .helpers.flow_node_instances import FlowNodeInstanceHandler, FlowNodeInstanceResponse, FlowNodeInstancesQuery
|
|
12
|
+
from .helpers.manual_tasks import ManualTaskHandler, ManualTaskQuery, ManualTaskResponse
|
|
13
|
+
from .helpers.user_tasks import UserTaskHandler, UserTaskQuery, UserTaskResponse, ReserveUserTaskRequest
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from typing import Callable, Dict, Type
|
|
3
|
+
from requests.api import request
|
|
4
|
+
from typing_extensions import Protocol
|
|
5
|
+
import json
|
|
6
|
+
|
|
7
|
+
import requests
|
|
8
|
+
|
|
9
|
+
class IsDataclass(Protocol):
|
|
10
|
+
__dataclass_fields__: Dict
|
|
11
|
+
|
|
12
|
+
class BaseClient(object):
|
|
13
|
+
|
|
14
|
+
def __init__(self, url: str, identity: Callable=None):
|
|
15
|
+
self._url = url
|
|
16
|
+
|
|
17
|
+
if identity is not None:
|
|
18
|
+
self._identity = identity
|
|
19
|
+
else:
|
|
20
|
+
self._identity = lambda: {"token": "ZHVtbXlfdG9rZW4="}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def do_get(self, path: str, options: Dict={}):
|
|
24
|
+
headers = self.__get_default_headers()
|
|
25
|
+
headers.update(options.get('headers', {}))
|
|
26
|
+
headers.update(self.__get_auth_headers())
|
|
27
|
+
|
|
28
|
+
request_url = f"{self._url}{path}"
|
|
29
|
+
|
|
30
|
+
response = requests.get(request_url, headers=headers)
|
|
31
|
+
|
|
32
|
+
response.raise_for_status()
|
|
33
|
+
|
|
34
|
+
json_body = response.json()
|
|
35
|
+
|
|
36
|
+
return json_body
|
|
37
|
+
|
|
38
|
+
def do_delete(self, path: str, options: Dict={}):
|
|
39
|
+
headers = self.__get_default_headers()
|
|
40
|
+
headers.update(options.get('headers', {}))
|
|
41
|
+
headers.update(self.__get_auth_headers())
|
|
42
|
+
|
|
43
|
+
request_url = f"{self._url}{path}"
|
|
44
|
+
|
|
45
|
+
response = requests.delete(request_url, headers=headers)
|
|
46
|
+
|
|
47
|
+
response.raise_for_status()
|
|
48
|
+
|
|
49
|
+
def do_post(self, path: str, payload: IsDataclass, options: Dict={}):
|
|
50
|
+
headers = self.__get_default_headers()
|
|
51
|
+
headers.update(options.get('headers', {}))
|
|
52
|
+
headers.update(self.__get_auth_headers())
|
|
53
|
+
|
|
54
|
+
request_url = f"{self._url}{path}"
|
|
55
|
+
|
|
56
|
+
json_payload = json.dumps(payload)
|
|
57
|
+
|
|
58
|
+
response = requests.post(request_url, json_payload, headers=headers)
|
|
59
|
+
|
|
60
|
+
response.raise_for_status()
|
|
61
|
+
|
|
62
|
+
if response.status_code == 200:
|
|
63
|
+
json_body = response.json()
|
|
64
|
+
else:
|
|
65
|
+
json_body = {}
|
|
66
|
+
|
|
67
|
+
return json_body
|
|
68
|
+
|
|
69
|
+
def do_put(self, path: str, payload: IsDataclass, options: Dict={}):
|
|
70
|
+
headers = self.__get_default_headers()
|
|
71
|
+
headers.update(options.get('headers', {}))
|
|
72
|
+
headers.update(self.__get_auth_headers())
|
|
73
|
+
|
|
74
|
+
request_url = f"{self._url}{path}"
|
|
75
|
+
|
|
76
|
+
json_payload = json.dumps(payload)
|
|
77
|
+
|
|
78
|
+
response = requests.put(request_url, json_payload, headers=headers)
|
|
79
|
+
|
|
80
|
+
response.raise_for_status()
|
|
81
|
+
|
|
82
|
+
if response.status_code == 200:
|
|
83
|
+
json_body = response.json()
|
|
84
|
+
else:
|
|
85
|
+
json_body = {}
|
|
86
|
+
|
|
87
|
+
return json_body
|
|
88
|
+
|
|
89
|
+
def __get_auth_headers(self):
|
|
90
|
+
identity = self.__get_identity()
|
|
91
|
+
token = identity['token']
|
|
92
|
+
return {'Authorization': 'Bearer {}'.format(token)}
|
|
93
|
+
|
|
94
|
+
def __get_default_headers(self):
|
|
95
|
+
return {'Content-Type': 'application/json'}
|
|
96
|
+
|
|
97
|
+
def __get_identity(self):
|
|
98
|
+
identity = self._identity
|
|
99
|
+
|
|
100
|
+
if callable(self._identity):
|
|
101
|
+
identity = self._identity()
|
|
102
|
+
|
|
103
|
+
return identity
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
from typing import Any, Callable, Dict, List
|
|
5
|
+
|
|
6
|
+
from dataclasses import dataclass, field
|
|
7
|
+
from dataclasses_json import dataclass_json, LetterCase
|
|
8
|
+
|
|
9
|
+
from .helpers.application_info import ApplicationInfo, ApplicationInfoHandler
|
|
10
|
+
from .helpers.data_object_instances import DataObjectInstanceHandler, DataObjectInstancesQuery, DataObjectInstanceResponse
|
|
11
|
+
from .helpers.empty_tasks import EmptyTaskHandler, EmptyTaskQuery, EmptyTaskResponse
|
|
12
|
+
from .helpers.events import EventsHandler, MessageTriggerRequest
|
|
13
|
+
from .helpers.external_tasks import ExtendLockRequest, FetchAndLockRequestPayload, ExternalTask
|
|
14
|
+
from .helpers.external_tasks import ExternalTaskHandler, FinishExternalTaskRequestPayload
|
|
15
|
+
from .helpers.flow_node_instances import FlowNodeInstanceHandler, FlowNodeInstanceResponse, FlowNodeInstancesQuery
|
|
16
|
+
from .helpers.manual_tasks import ManualTaskHandler, ManualTaskQuery, ManualTaskResponse
|
|
17
|
+
from .helpers.external_tasks import BpmnErrorRequest, ServiceErrorRequest
|
|
18
|
+
from .helpers.process_definitions import ProcessDefinitionUploadPayload, ProcessDefinitionHandler
|
|
19
|
+
from .helpers.process_instances import ProcessInstanceHandler, ProcessInstanceQueryRequest, ProcessInstanceQueryResponse
|
|
20
|
+
from .helpers.process_models import ProcessStartRequest, ProcessStartResponse, ProcessModelHandler
|
|
21
|
+
from .helpers.user_tasks import UserTaskHandler, UserTaskQuery, UserTaskResponse, ReserveUserTaskRequest
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass_json(letter_case=LetterCase.CAMEL)
|
|
25
|
+
@dataclass
|
|
26
|
+
class DeployResult:
|
|
27
|
+
filename: str
|
|
28
|
+
deployed: bool = True
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@dataclass_json(letter_case=LetterCase.CAMEL)
|
|
32
|
+
@dataclass
|
|
33
|
+
class DeployResults:
|
|
34
|
+
deployed_files: List[DeployResult] = field(default_factory=list)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class Client(object):
|
|
38
|
+
|
|
39
|
+
def __init__(self, url: str, identity: Callable = None):
|
|
40
|
+
self._url = url
|
|
41
|
+
self._identity = identity
|
|
42
|
+
|
|
43
|
+
def info(self) -> ApplicationInfo:
|
|
44
|
+
handler = ApplicationInfoHandler(self._url, self._identity)
|
|
45
|
+
|
|
46
|
+
application_info = handler.info()
|
|
47
|
+
|
|
48
|
+
return application_info
|
|
49
|
+
|
|
50
|
+
def authority(self) -> str:
|
|
51
|
+
handler = ApplicationInfoHandler(self._url, self._identity)
|
|
52
|
+
|
|
53
|
+
authority = handler.authority()
|
|
54
|
+
|
|
55
|
+
return authority
|
|
56
|
+
|
|
57
|
+
def data_object_instance_get(self, query: DataObjectInstancesQuery, options: dict = {}) -> DataObjectInstanceResponse:
|
|
58
|
+
handler = DataObjectInstanceHandler(self._url, self._identity)
|
|
59
|
+
|
|
60
|
+
response = handler.get_data_object_instances(query, options)
|
|
61
|
+
|
|
62
|
+
return response
|
|
63
|
+
|
|
64
|
+
def empty_task_get(self, empty_task_query: EmptyTaskQuery, options: dict = {}) -> EmptyTaskResponse:
|
|
65
|
+
handler = EmptyTaskHandler(self._url, self._identity)
|
|
66
|
+
|
|
67
|
+
response = handler.get_empty_tasks(empty_task_query, options)
|
|
68
|
+
|
|
69
|
+
return response
|
|
70
|
+
|
|
71
|
+
def empty_task_finish(self, empty_task_instance_id: str, options: dict = {}):
|
|
72
|
+
handler = EmptyTaskHandler(self._url, self._identity)
|
|
73
|
+
|
|
74
|
+
_ = handler.finish_empty_task(empty_task_instance_id, options)
|
|
75
|
+
|
|
76
|
+
return True
|
|
77
|
+
|
|
78
|
+
def events_trigger_message(self, event_name: str, request: MessageTriggerRequest, options: dict = {}):
|
|
79
|
+
handler = EventsHandler(self._url, self._identity)
|
|
80
|
+
|
|
81
|
+
handler.trigger_message(event_name, request, options)
|
|
82
|
+
|
|
83
|
+
def events_trigger_signal(self, signal_name: str, options: dict = {}):
|
|
84
|
+
handler = EventsHandler(self._url, self._identity)
|
|
85
|
+
|
|
86
|
+
handler.trigger_signal(signal_name, options)
|
|
87
|
+
|
|
88
|
+
def external_task_fetch_and_lock(self, request: FetchAndLockRequestPayload, options: dict = {}) -> List[ExternalTask]:
|
|
89
|
+
handler = ExternalTaskHandler(self._url, self._identity)
|
|
90
|
+
|
|
91
|
+
reponse = handler.fetch_and_lock(request, options)
|
|
92
|
+
|
|
93
|
+
return reponse
|
|
94
|
+
|
|
95
|
+
def external_task_extend_lock(self, request: ExtendLockRequest, options: dict = {}) -> List[ExternalTask]:
|
|
96
|
+
handler = ExternalTaskHandler(self._url, self._identity)
|
|
97
|
+
|
|
98
|
+
reponse = handler.extend_lock(request, options)
|
|
99
|
+
|
|
100
|
+
return reponse
|
|
101
|
+
|
|
102
|
+
def external_task_finish(self, external_task_id: str, request: FinishExternalTaskRequestPayload, options: dict = {}):
|
|
103
|
+
handler = ExternalTaskHandler(self._url, self._identity)
|
|
104
|
+
|
|
105
|
+
response = handler.finish(external_task_id, request, options)
|
|
106
|
+
|
|
107
|
+
return response
|
|
108
|
+
|
|
109
|
+
def external_task_handle_bpmn_error(self, external_task_id: str, request: BpmnErrorRequest, options: dict = {}):
|
|
110
|
+
handler = ExternalTaskHandler(self._url, self._identity)
|
|
111
|
+
|
|
112
|
+
response = handler.handle_bpmn_error(
|
|
113
|
+
external_task_id, request, options)
|
|
114
|
+
|
|
115
|
+
return response
|
|
116
|
+
|
|
117
|
+
def external_task_handle_service_error(self, external_task_id: str, request: ServiceErrorRequest, options: dict = {}):
|
|
118
|
+
handler = ExternalTaskHandler(self._url, self._identity)
|
|
119
|
+
|
|
120
|
+
response = handler.handle_service_error(
|
|
121
|
+
external_task_id, request, options)
|
|
122
|
+
|
|
123
|
+
return response
|
|
124
|
+
|
|
125
|
+
def flow_node_instance_get(self, query: FlowNodeInstancesQuery, options: dict = {}) -> FlowNodeInstanceResponse:
|
|
126
|
+
handler = FlowNodeInstanceHandler(self._url, self._identity)
|
|
127
|
+
|
|
128
|
+
response = handler.get_flow_node_instances(query, options)
|
|
129
|
+
|
|
130
|
+
return response
|
|
131
|
+
|
|
132
|
+
def manual_task_get(self, manual_task_query: ManualTaskQuery, options: dict = {}) -> ManualTaskResponse:
|
|
133
|
+
handler = ManualTaskHandler(self._url, self._identity)
|
|
134
|
+
|
|
135
|
+
response = handler.get_manual_tasks(manual_task_query, options)
|
|
136
|
+
|
|
137
|
+
return response
|
|
138
|
+
|
|
139
|
+
def manual_task_finish(self, manual_task_instance_id: str, options: dict = {}):
|
|
140
|
+
handler = ManualTaskHandler(self._url, self._identity)
|
|
141
|
+
|
|
142
|
+
_ = handler.finish_manual_task(manual_task_instance_id, options)
|
|
143
|
+
|
|
144
|
+
return True
|
|
145
|
+
|
|
146
|
+
def process_defintion_deploy(self, request: ProcessDefinitionUploadPayload, options: dict = {}):
|
|
147
|
+
handler = ProcessDefinitionHandler(self._url, self._identity)
|
|
148
|
+
|
|
149
|
+
handler.deploy(request, options)
|
|
150
|
+
|
|
151
|
+
def process_defintion_deploy_by_pathname(self, pathname: str, exit_on_fail: bool = False, overwrite_existing: bool = True, options: dict = {}) -> DeployResults:
|
|
152
|
+
|
|
153
|
+
handler = ProcessDefinitionHandler(self._url, self._identity)
|
|
154
|
+
|
|
155
|
+
deploy_results = DeployResults()
|
|
156
|
+
|
|
157
|
+
filenames = []
|
|
158
|
+
|
|
159
|
+
if Path(pathname).is_file():
|
|
160
|
+
filenames.append(pathname)
|
|
161
|
+
else:
|
|
162
|
+
found_paths = Path(os.getcwd()).rglob(pathname)
|
|
163
|
+
filenames = [str(path) for path in found_paths]
|
|
164
|
+
|
|
165
|
+
if len(filenames) == 0 and exit_on_fail:
|
|
166
|
+
raise Exception(f"No files found for pathname {pathname}")
|
|
167
|
+
|
|
168
|
+
has_failed_deployments = False
|
|
169
|
+
|
|
170
|
+
for filename in filenames:
|
|
171
|
+
|
|
172
|
+
deployed_file = DeployResult(filename=filename)
|
|
173
|
+
deploy_results.deployed_files.append(deployed_file)
|
|
174
|
+
|
|
175
|
+
with open(filename) as file:
|
|
176
|
+
xml = file.read()
|
|
177
|
+
|
|
178
|
+
request = ProcessDefinitionUploadPayload(
|
|
179
|
+
xml=xml, overwrite_existing=overwrite_existing)
|
|
180
|
+
|
|
181
|
+
try:
|
|
182
|
+
handler.deploy(request, options=options)
|
|
183
|
+
deployed_file.deployed = True
|
|
184
|
+
except Exception as e:
|
|
185
|
+
if exit_on_fail:
|
|
186
|
+
raise e
|
|
187
|
+
else:
|
|
188
|
+
deployed_file.deployed = False
|
|
189
|
+
has_failed_deployments = True
|
|
190
|
+
|
|
191
|
+
if has_failed_deployments and exit_on_fail:
|
|
192
|
+
failed_filenames = [
|
|
193
|
+
deploy_result.filename for deploy_result in deploy_results if deploy_result.deployed == False]
|
|
194
|
+
msg = f'Failed to deploy {",".join(failed_filenames)}'
|
|
195
|
+
raise Exception(msg)
|
|
196
|
+
|
|
197
|
+
if len(filenames) != len(deploy_results.deployed_files) or len(deploy_results.deployed_files) == 0:
|
|
198
|
+
if exit_on_fail:
|
|
199
|
+
msg = f"Nothing to deploy with '{pathname}' in current working dir '{os.getcwd()}'"
|
|
200
|
+
raise Exception(msg)
|
|
201
|
+
|
|
202
|
+
return deploy_results
|
|
203
|
+
|
|
204
|
+
def process_instanceq_query(self, request: ProcessInstanceQueryRequest, options: dict = {}) -> ProcessInstanceQueryResponse:
|
|
205
|
+
return self.process_instance_query(request, options)
|
|
206
|
+
|
|
207
|
+
def process_instance_query(self, request: ProcessInstanceQueryRequest, options: dict = {}) -> ProcessInstanceQueryResponse:
|
|
208
|
+
handler = ProcessInstanceHandler(self._url, self._identity)
|
|
209
|
+
|
|
210
|
+
response = handler.query(request, options)
|
|
211
|
+
|
|
212
|
+
return response
|
|
213
|
+
|
|
214
|
+
def process_instance_terminate(self, process_instance_id: str, options: dict = {}):
|
|
215
|
+
handler = ProcessInstanceHandler(self._url, self._identity)
|
|
216
|
+
|
|
217
|
+
response = handler.terminate(process_instance_id, options)
|
|
218
|
+
|
|
219
|
+
return response
|
|
220
|
+
|
|
221
|
+
def process_model_start(self, process_model_id: str, request: ProcessStartRequest, options: dict = {}) -> ProcessStartResponse:
|
|
222
|
+
handler = ProcessModelHandler(self._url, self._identity)
|
|
223
|
+
|
|
224
|
+
response = handler.start(process_model_id, request, options)
|
|
225
|
+
|
|
226
|
+
return response
|
|
227
|
+
|
|
228
|
+
def user_task_get(self, query: UserTaskQuery = UserTaskQuery(), options: dict = {}) -> UserTaskResponse:
|
|
229
|
+
handler = UserTaskHandler(self._url, self._identity)
|
|
230
|
+
|
|
231
|
+
response = handler.get_user_tasks(query, options)
|
|
232
|
+
|
|
233
|
+
return response
|
|
234
|
+
|
|
235
|
+
def user_task_reserve(self, user_task_instance_id: str, request: ReserveUserTaskRequest, options: dict = {}):
|
|
236
|
+
handler = UserTaskHandler(self._url, self._identity)
|
|
237
|
+
|
|
238
|
+
response = handler.reserve_user_task(
|
|
239
|
+
user_task_instance_id, request, options)
|
|
240
|
+
|
|
241
|
+
return response
|
|
242
|
+
|
|
243
|
+
def user_task_cancel_reservation(self, user_task_instance_id: str, options: dict = {}):
|
|
244
|
+
handler = UserTaskHandler(self._url, self._identity)
|
|
245
|
+
|
|
246
|
+
response = handler.cancel_reservation(user_task_instance_id, options)
|
|
247
|
+
|
|
248
|
+
return response
|
|
249
|
+
|
|
250
|
+
def user_task_finish(self, user_task_instance_id: str, request: Dict[str, Any], options: dict = {}):
|
|
251
|
+
handler = UserTaskHandler(self._url, self._identity)
|
|
252
|
+
|
|
253
|
+
response = handler.finish_user_task(
|
|
254
|
+
user_task_instance_id, request, options)
|
|
255
|
+
|
|
256
|
+
return response
|
|
File without changes
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from dataclasses_json import dataclass_json, LetterCase
|
|
5
|
+
from typing import Callable
|
|
6
|
+
|
|
7
|
+
from ..base_client import BaseClient
|
|
8
|
+
|
|
9
|
+
@dataclass_json(letter_case=LetterCase.CAMEL)
|
|
10
|
+
@dataclass
|
|
11
|
+
class ApplicationInfo:
|
|
12
|
+
id: str
|
|
13
|
+
name: str
|
|
14
|
+
package_name: str
|
|
15
|
+
version: str
|
|
16
|
+
authority_url: str
|
|
17
|
+
allow_anonymous_root_access: str
|
|
18
|
+
extra_info: dict
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class ApplicationInfoHandler(BaseClient):
|
|
22
|
+
|
|
23
|
+
def __init__(self, url: str, identity: Callable=None):
|
|
24
|
+
super(ApplicationInfoHandler, self).__init__(url, identity)
|
|
25
|
+
|
|
26
|
+
def info(self) -> ApplicationInfo:
|
|
27
|
+
json_data = self.do_get('/atlas_engine/api/v1/info')
|
|
28
|
+
|
|
29
|
+
info = ApplicationInfo.from_dict(json_data)
|
|
30
|
+
|
|
31
|
+
return info
|
|
32
|
+
|
|
33
|
+
def authority(self) -> str:
|
|
34
|
+
json_data = self.do_get('/atlas_engine/api/v1/authority')
|
|
35
|
+
|
|
36
|
+
return json_data
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
from dataclasses import dataclass, field
|
|
2
|
+
from dataclasses_json import dataclass_json, LetterCase, Undefined
|
|
3
|
+
from dataclasses_json import CatchAll
|
|
4
|
+
from typing import Any, Callable, Dict, Optional
|
|
5
|
+
from urllib import parse
|
|
6
|
+
|
|
7
|
+
from ..base_client import BaseClient
|
|
8
|
+
|
|
9
|
+
@dataclass_json(letter_case=LetterCase.CAMEL)
|
|
10
|
+
@dataclass
|
|
11
|
+
class DataObjectInstancesQuery:
|
|
12
|
+
limit: int = None
|
|
13
|
+
offset: int = None
|
|
14
|
+
data_object_id: str = None
|
|
15
|
+
process_definition_id: str = None
|
|
16
|
+
process_model_id: str = None
|
|
17
|
+
process_instance_id: str = None
|
|
18
|
+
flow_node_instance_id: str = None
|
|
19
|
+
|
|
20
|
+
@dataclass_json(letter_case=LetterCase.CAMEL, undefined=Undefined.INCLUDE)
|
|
21
|
+
@dataclass
|
|
22
|
+
class DataObjectInstanceResponse:
|
|
23
|
+
data_object_id: Optional[str] = None
|
|
24
|
+
flow_node_instance_id: Optional[str] = None
|
|
25
|
+
process_definition_id: Optional[str] = None
|
|
26
|
+
process_model_id: Optional[str] = None
|
|
27
|
+
process_instance_id: Optional[str] = None
|
|
28
|
+
value: Dict[str, Any] = field(default_factory=dict)
|
|
29
|
+
created_at: Optional[str] = None
|
|
30
|
+
updated_at: Optional[str] = None
|
|
31
|
+
place_holder: CatchAll = None
|
|
32
|
+
|
|
33
|
+
class DataObjectInstanceHandler(BaseClient):
|
|
34
|
+
|
|
35
|
+
def __init__(self, url: str, identity: Callable=None):
|
|
36
|
+
super(DataObjectInstanceHandler, self).__init__(url, identity)
|
|
37
|
+
|
|
38
|
+
def get_data_object_instances(self, query: DataObjectInstancesQuery, options: dict={}) -> DataObjectInstanceResponse:
|
|
39
|
+
|
|
40
|
+
query_dict = query.to_dict()
|
|
41
|
+
|
|
42
|
+
filtered_query = list(filter(lambda dict_entry: dict_entry[1] is not None, query_dict.items()))
|
|
43
|
+
|
|
44
|
+
query_str = parse.urlencode(filtered_query, doseq=False)
|
|
45
|
+
|
|
46
|
+
path = f"/atlas_engine/api/v1/data_object_instances/query?{query_str}"
|
|
47
|
+
|
|
48
|
+
response_list_of_dict = self.do_get(path, options)
|
|
49
|
+
|
|
50
|
+
if response_list_of_dict.get('totalCount', 0) > 0:
|
|
51
|
+
json_data = response_list_of_dict['dataObjectInstances']
|
|
52
|
+
response = DataObjectInstanceResponse.schema().load(json_data, many=True)
|
|
53
|
+
else:
|
|
54
|
+
response = []
|
|
55
|
+
|
|
56
|
+
return response
|