Skip to content

Commit fdb8783

Browse files
authored
add robocorp client
1 parent 71df507 commit fdb8783

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+1375
-91
lines changed

.github/workflows/main.yml

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,31 @@
1-
name: External Worker Build and Test
1+
name: Flowable External Client Build and Test
22

33
on: [push, pull_request]
44

55
jobs:
6-
build:
6+
test-external-worker-client:
7+
runs-on: ubuntu-latest
8+
strategy:
9+
matrix:
10+
python-version: ["3.12.0"]
711

12+
steps:
13+
- uses: actions/checkout@v4
14+
- name: Set up Python ${{ matrix.python-version }}
15+
uses: actions/setup-python@v4
16+
with:
17+
python-version: ${{ matrix.python-version }}
18+
- name: Display Python version
19+
run: python -c "import sys; print(sys.version)"
20+
- run: pip install virtualenv
21+
- run: virtualenv venv
22+
- run: source venv/bin/activate
23+
- run: pip install setuptools
24+
- run: pip install -e ".[testing]"
25+
working-directory: ./external-worker/
26+
- run: python -m unittest discover
27+
working-directory: ./external-worker/
28+
test-robocorp-client:
829
runs-on: ubuntu-latest
930
strategy:
1031
matrix:
@@ -22,4 +43,10 @@ jobs:
2243
- run: virtualenv venv
2344
- run: source venv/bin/activate
2445
- run: pip install setuptools
25-
- run: python setup.py pytest
46+
- run: python setup.py install
47+
working-directory: ./external-worker/
48+
- run: pip install -e ".[testing]"
49+
working-directory: ./robocorp/
50+
- run: cp -a external-worker/flowable/external_worker_client robocorp/flowable/ # we need to copy this module over, since it's only searching locally for modules
51+
- run: python -m unittest discover
52+
working-directory: ./robocorp/

.github/workflows/release.yml

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,38 @@ jobs:
2222
- run: source venv/bin/activate
2323
- run: pip install setuptools
2424
- run: python setup.py sdist
25+
working-directory: ./external-worker/
2526
- run: pip wheel --no-deps . -w dist
27+
working-directory: ./external-worker/
2628
- name: Publish package distributions to PyPI
2729
uses: pypa/gh-action-pypi-publish@release/v1
2830
with:
29-
packages-dir: dist/
31+
packages-dir: external-worker/dist/
32+
verbose: true
33+
34+
build-robocorp-client:
35+
runs-on: ubuntu-latest
36+
environment: release
37+
permissions:
38+
id-token: write
39+
steps:
40+
- uses: actions/checkout@v4
41+
- name: Set up Python 3.12.0
42+
uses: actions/setup-python@v4
43+
with:
44+
python-version: 3.12.0
45+
- name: Display Python version
46+
run: python -c "import sys; print(sys.version)"
47+
- run: pip install virtualenv
48+
- run: virtualenv venv
49+
- run: source venv/bin/activate
50+
- run: pip install setuptools
51+
- run: python setup.py sdist
52+
working-directory: ./robocorp/
53+
- run: pip wheel --no-deps . -w dist
54+
working-directory: ./robocorp/
55+
- name: Publish package distributions to PyPI
56+
uses: pypa/gh-action-pypi-publish@release/v1
57+
with:
58+
packages-dir: robocorp/dist/
3059
verbose: true

.github/workflows/test-release.yml

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ on:
66
- v*
77

88
jobs:
9-
build:
9+
build-external-worker-client:
1010
runs-on: ubuntu-latest
1111
environment: release
1212
permissions:
@@ -24,10 +24,40 @@ jobs:
2424
- run: source venv/bin/activate
2525
- run: pip install setuptools
2626
- run: python setup.py sdist
27+
working-directory: ./external-worker/
2728
- run: pip wheel --no-deps . -w dist
29+
working-directory: ./external-worker/
2830
- name: Publish package distributions to Test PyPI
2931
uses: pypa/gh-action-pypi-publish@release/v1
3032
with:
3133
repository-url: https://test.pypi.org/legacy/
32-
packages-dir: dist/
34+
packages-dir: external-worker/dist/
35+
verbose: true
36+
37+
build-robocorp-client:
38+
runs-on: ubuntu-latest
39+
environment: release
40+
permissions:
41+
id-token: write
42+
steps:
43+
- uses: actions/checkout@v4
44+
- name: Set up Python 3.12.0
45+
uses: actions/setup-python@v4
46+
with:
47+
python-version: 3.12.0
48+
- name: Display Python version
49+
run: python -c "import sys; print(sys.version)"
50+
- run: pip install virtualenv
51+
- run: virtualenv venv
52+
- run: source venv/bin/activate
53+
- run: pip install setuptools
54+
- run: python setup.py sdist
55+
working-directory: ./robocorp/
56+
- run: pip wheel --no-deps . -w dist
57+
working-directory: ./robocorp/
58+
- name: Publish package distributions to Test PyPI
59+
uses: pypa/gh-action-pypi-publish@release/v1
60+
with:
61+
repository-url: https://test.pypi.org/legacy/
62+
packages-dir: robocorp/dist/
3363
verbose: true

README.md

Lines changed: 5 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,12 @@
1-
# Flowable External Worker Library for Python
2-
1+
# Flowable External Client Python
32

43
[License:
54
![license](https://img.shields.io/hexpm/l/plug.svg)](https://github.com/flowable/flowable-external-client-python/blob/main/LICENSE)
65

76
![Flowable Actions CI](https://github.com/flowable/flowable-external-client-python/actions/workflows/main.yml/badge.svg?branch=main)
87

9-
An _External Worker Task_ in BPMN or CMMN is a task where the custom logic of that task is executed externally to Flowable, i.e. on another server.
10-
When the process or case engine arrives at such a task, it will create an **external job**, which is exposed over the REST API.
11-
Through this REST API, the job can be acquired and locked.
12-
Once locked, the custom logic is responsible for signalling over REST that the work is done and the process or case can continue.
13-
14-
This project makes implementing such custom logic in Python easy by not having the worry about the low-level details of the REST API and focus on the actual custom business logic.
15-
Integrations for other languages are available, too.
16-
17-
## Authentication
18-
19-
The different ways to authenticate are explained in the [documentation of the underlying requests HTTP library which is used to connect to Flowable](https://requests.readthedocs.io/en/latest/user/authentication/).
20-
The `ExternalWorkerClient` accepts as a parameter `auth` an implementation of `requests.auth.AuthBase`.
21-
There are default implementations for example for basic authentication e.g. `HTTPBasicAuth("admin", "test")`.
22-
Flowable offers a bearer token implementation `FlowableCloudToken` which allows to specify an access token to the Flowable Cloud offering.
23-
24-
## Installation
25-
26-
To install the external worker library, execute the following command:
27-
28-
```
29-
pip install flowable.external-worker-client
30-
```
31-
32-
## Sample
33-
34-
### Cloud
35-
36-
The usage with Flowable Cloud is simpler, since everything is pre-configured.
37-
However, it's required to either use the user credentials or to pre-configure a personal access token.
38-
39-
```python
40-
from flowable.external_worker_client import ExternalWorkerClient
41-
from flowable.external_worker_client.cloud_token import FlowableCloudToken
42-
43-
client = ExternalWorkerClient(auth=FlowableCloudToken("<personal-access-token>"))
44-
45-
def my_callback(job, worker_result_builder):
46-
print('Executed job: ' + job.id)
47-
return worker_result_builder.success()
48-
49-
subscription = client.subscribe('myTopic', my_callback)
50-
```
51-
52-
### Local
53-
54-
The following is an example how you can connect to a Flowable instance running at `http://localhost:8090` and process all messages retrieved on the topic `myTopic`:
55-
56-
```python
57-
from flowable.external_worker_client import ExternalWorkerClient
58-
from requests.auth import HTTPBasicAuth
59-
60-
client = ExternalWorkerClient('http://localhost:8090/flowable-work', auth=HTTPBasicAuth("admin", "test"))
61-
62-
def my_callback(job, worker_result_builder):
63-
print('Executed job: ' + job.id)
64-
return worker_result_builder.success()
65-
66-
subscription = client.subscribe('myTopic', my_callback)
67-
```
8+
This is a collection of multiple Flowable Python clients.
9+
Currently, the project consists out of:
6810

11+
* [External Worker Client](./external-worker): A library to connect custom application code to Flowable with the external worker functionality
12+
* [Robocorp Client](./robocorp-client): A python module to execute Robocorp actions and tasks with the Flowable Robocorp task (based on the external worker).

external-worker/README.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Flowable External Worker Library for Python
2+
3+
4+
[License:
5+
![license](https://img.shields.io/hexpm/l/plug.svg)](https://github.com/flowable/flowable-external-client-python/blob/main/LICENSE)
6+
7+
![Flowable Actions CI](https://github.com/flowable/flowable-external-client-python/actions/workflows/main.yml/badge.svg?branch=main)
8+
9+
An _External Worker Task_ in BPMN or CMMN is a task where the custom logic of that task is executed externally to Flowable, i.e. on another server.
10+
When the process or case engine arrives at such a task, it will create an **external job**, which is exposed over the REST API.
11+
Through this REST API, the job can be acquired and locked.
12+
Once locked, the custom logic is responsible for signalling over REST that the work is done and the process or case can continue.
13+
14+
This project makes implementing such custom logic in Python easy by not having the worry about the low-level details of the REST API and focus on the actual custom business logic.
15+
Integrations for other languages are available, too.
16+
17+
## Authentication
18+
19+
The different ways to authenticate are explained in the [documentation of the underlying requests HTTP library which is used to connect to Flowable](https://requests.readthedocs.io/en/latest/user/authentication/).
20+
The `ExternalWorkerClient` accepts as a parameter `auth` an implementation of `requests.auth.AuthBase`.
21+
There are default implementations for example for basic authentication e.g. `HTTPBasicAuth("admin", "test")`.
22+
Flowable offers a bearer token implementation `FlowableCloudToken` which allows to specify an access token to the Flowable Cloud offering.
23+
24+
## Installation
25+
26+
To install the external worker library, execute the following command:
27+
28+
```
29+
pip install flowable.external-worker-client
30+
```
31+
32+
## Sample
33+
34+
### Cloud
35+
36+
The usage with Flowable Cloud is simpler, since everything is pre-configured.
37+
However, it's required to either use the user credentials or to pre-configure a personal access token.
38+
39+
```python
40+
from flowable.external_worker_client import ExternalWorkerClient
41+
from flowable.external_worker_client.cloud_token import FlowableCloudToken
42+
43+
client = ExternalWorkerClient(auth=FlowableCloudToken("<personal-access-token>"))
44+
45+
def my_callback(job, worker_result_builder):
46+
print('Executed job: ' + job.id)
47+
return worker_result_builder.success()
48+
49+
subscription = client.subscribe('myTopic', my_callback)
50+
```
51+
52+
### Local
53+
54+
The following is an example how you can connect to a Flowable instance running at `http://localhost:8090` and process all messages retrieved on the topic `myTopic`:
55+
56+
```python
57+
from flowable.external_worker_client import ExternalWorkerClient
58+
from requests.auth import HTTPBasicAuth
59+
60+
client = ExternalWorkerClient('http://localhost:8090/flowable-work', auth=HTTPBasicAuth("admin", "test"))
61+
62+
def my_callback(job, worker_result_builder):
63+
print('Executed job: ' + job.id)
64+
return worker_result_builder.success()
65+
66+
subscription = client.subscribe('myTopic', my_callback)
67+
```
File renamed without changes.

flowable/external_worker_client/__init__.py renamed to external-worker/flowable/external_worker_client/__init__.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import sys
12
import threading
23
import time
34
from os import getpid
@@ -52,7 +53,7 @@ class ExternalWorkerClient(object):
5253

5354
def __init__(
5455
self,
55-
flowable_host: str = "https://cloud.flowable.com/work",
56+
flowable_host: str = "https://trial.flowable.com/work",
5657
worker_id: str = None,
5758
auth: AuthBase = None,
5859
customize_session: Callable[[Session], None] = lambda session: None
@@ -103,5 +104,7 @@ def _consume(
103104
result.execute(self._restClient)
104105
else:
105106
self._restClient.complete_job(job.id)
106-
except:
107-
self._restClient.fail_job(job.id)
107+
except Exception as e:
108+
print("An error occurred during job execution " + job.id, file=sys.stderr)
109+
print(e, file=sys.stderr)
110+
self._restClient.fail_job(job.id, e.__str__())

flowable/external_worker_client/restclient.py renamed to external-worker/flowable/external_worker_client/restclient.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ def acquire_jobs(
8585
}
8686
)
8787
if r.status_code != 200:
88+
print(r.text)
8889
raise FlowableRestException(r.status_code, r.text)
8990

9091
return list(map(response_converter.convert_to_external_worker_acquire_job_response, r.json()))
Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
from setuptools import find_packages, setup
2-
31
# read the contents of your README file
42
from pathlib import Path
53

4+
from setuptools import setup
5+
66
this_directory = Path(__file__).parent
77
long_description = (this_directory / "README.md").read_text()
88

99
setup(
1010
name='flowable.external-worker-client',
1111
packages=['flowable', 'flowable.external_worker_client'],
12-
version='1.0.0',
12+
version='1.0.1rc1',
1313
description='Flowable External Worker Library to connect Python code to Flowable using an external worker.',
1414
long_description=long_description,
1515
long_description_content_type='text/markdown',
1616
author='Flowable',
17-
license='',
17+
license='Apache License, Version 2.0',
1818
install_requires=['requests>=2.27.0'],
19-
setup_requires=['pytest-runner'],
20-
tests_require=['pytest', 'vcrpy'],
21-
test_suite='tests',
19+
extras_require={
20+
'testing': ['pytest', 'vcrpy']
21+
},
2222
)
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)