From 2bbdf8a0d676dccf8333a093add95ff50c75fc54 Mon Sep 17 00:00:00 2001 From: jasquat Date: Wed, 20 Jul 2022 15:18:57 -0400 Subject: [PATCH 01/20] added api endpoint to get previously completed user tasks --- src/spiffworkflow_backend/api.yml | 32 +- .../models/active_task.py | 2 + src/spiffworkflow_backend/models/task.py | 20 + .../routes/process_api_blueprint.py | 153 ++++- test.json | 1 + test2.json | 596 ++++++++++++++++++ 6 files changed, 780 insertions(+), 24 deletions(-) create mode 100644 test.json create mode 100644 test2.json diff --git a/src/spiffworkflow_backend/api.yml b/src/spiffworkflow_backend/api.yml index 1cbe6065..05356176 100755 --- a/src/spiffworkflow_backend/api.yml +++ b/src/spiffworkflow_backend/api.yml @@ -672,9 +672,9 @@ paths: items: # $ref: "#/components/schemas/ActiveTask" $ref: "#/components/schemas/Task" - /tasks/{task_id}: + /tasks/{active_task_id}: parameters: - - name: task_id + - name: active_task_id in: path required: true description: The unique id of an existing process group. @@ -690,9 +690,33 @@ paths: application/json: schema: $ref: "#/components/schemas/Task" - /tasks/{task_id}/submit: + /tasks/completed_user_task/{process_instance_id}/{spiffworkflow_task_id}: parameters: - - name: task_id + - name: process_instance_id + in: path + required: true + description: The unique id of an existing process instance. + schema: + type: integer + - name: spiffworkflow_task_id + in: path + required: true + description: The unique id of an existing process group. + schema: + type: string + get: + operationId: spiffworkflow_backend.routes.process_api_blueprint.task_show_completed_user_task + summary: Gets one task that a user wants to complete + responses: + "200": + description: One task + content: + application/json: + schema: + $ref: "#/components/schemas/Task" + /tasks/{active_task_id}/submit: + parameters: + - name: active_task_id in: path required: true description: The unique id of an existing process group. diff --git a/src/spiffworkflow_backend/models/active_task.py b/src/spiffworkflow_backend/models/active_task.py index 1f4f0a88..113b9fc1 100644 --- a/src/spiffworkflow_backend/models/active_task.py +++ b/src/spiffworkflow_backend/models/active_task.py @@ -26,6 +26,8 @@ class ActiveTaskModel(SpiffworkflowBaseDBModel): form_json: str | None = "" bpmn_json: str = "" + preceding_spiffworkflow_user_task_id: int | None = None + assigned_principal: RelationshipProperty[PrincipalModel] = relationship( PrincipalModel ) diff --git a/src/spiffworkflow_backend/models/task.py b/src/spiffworkflow_backend/models/task.py index 9c039c05..dccbe9a1 100644 --- a/src/spiffworkflow_backend/models/task.py +++ b/src/spiffworkflow_backend/models/task.py @@ -110,6 +110,12 @@ class Task: multi_instance_index: str, process_name: str, properties: dict, + process_instance_id: int | None = None, + form_schema: str | None = None, + form_ui_schema: str | None = None, + preceding_spiffworkflow_user_task_id: str | int | None = None, + following_spiffworkflow_user_task_id: str | int | None = None, + current_active_task_id: int | None = None, ): """__init__.""" self.id = id @@ -121,6 +127,14 @@ class Task: self.documentation = documentation self.data = data self.lane = lane + + self.process_instance_id = process_instance_id + self.form_schema = form_schema + self.form_ui_schema = form_ui_schema + self.preceding_spiffworkflow_user_task_id = preceding_spiffworkflow_user_task_id + self.following_spiffworkflow_user_task_id = following_spiffworkflow_user_task_id + self.current_active_task_id = current_active_task_id + self.multi_instance_type = ( multi_instance_type # Some tasks have a repeat behavior. ) @@ -228,6 +242,12 @@ class TaskSchema(Schema): "multi_instance_index", "process_name", "properties", + "process_instance_id", + "form_schema", + "form_ui_schema", + "preceding_spiffworkflow_user_task_id", + "following_spiffworkflow_user_task_id", + "current_active_task_id", ] multi_instance_type = EnumField(MultiInstanceType) diff --git a/src/spiffworkflow_backend/routes/process_api_blueprint.py b/src/spiffworkflow_backend/routes/process_api_blueprint.py index 16ef5588..24a6326d 100644 --- a/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -35,6 +35,7 @@ from spiffworkflow_backend.models.process_instance_report import ( ) from spiffworkflow_backend.models.process_model import ProcessModelInfo from spiffworkflow_backend.models.process_model import ProcessModelInfoSchema +from spiffworkflow_backend.models.task import TaskSchema from spiffworkflow_backend.services.error_handling_service import ErrorHandlingService from spiffworkflow_backend.services.process_instance_processor import ( ProcessInstanceProcessor, @@ -550,11 +551,13 @@ def task_list_my_tasks(page: int = 1, per_page: int = 100) -> flask.wrappers.Res return make_response(jsonify(response_json), 200) -def task_show(task_id: int) -> flask.wrappers.Response: +def task_show(active_task_id: int) -> flask.wrappers.Response: """Task_list_my_tasks.""" principal = find_principal_or_raise() - active_task_assigned_to_me = find_active_task_by_id_or_raise(task_id, principal.id) + active_task_assigned_to_me = find_active_task_by_id_or_raise( + active_task_id, principal.id + ) process_instance = find_process_instance_by_id_or_raise( active_task_assigned_to_me.process_instance_id @@ -568,35 +571,120 @@ def task_show(task_id: int) -> flask.wrappers.Response: raise ( ApiError( code="missing_form_file", - message=f"Cannot find a form file for active task {task_id}", + message=f"Cannot find a form file for active task {active_task_id}", status_code=500, ) ) - file_contents = SpecFileService.get_data( - process_model, active_task_assigned_to_me.form_file_name - ).decode("utf-8") - - spiffworkflow_data_json = json.loads( - active_task_assigned_to_me.spiffworkflow_task_data + form_contents = prepare_form_data( + active_task_assigned_to_me.form_file_name, + json.loads(active_task_assigned_to_me.spiffworkflow_task_data), + process_model, ) + if form_contents: + active_task_assigned_to_me.form_json = form_contents - # trade out pieces like "{{variable_name}}" for the corresponding form data value - for key, value in spiffworkflow_data_json.items(): - if isinstance(value, str) or isinstance(value, int): - file_contents = file_contents.replace("{{" + key + "}}", str(value)) - - active_task_assigned_to_me.form_json = file_contents + # FIXME: This should be stored in the db when the active task is created + processor = ProcessInstanceProcessor(process_instance) + if processor.completed_user_tasks(): + active_task_assigned_to_me.preceding_spiffworkflow_user_task_id = ( + processor.completed_user_tasks()[0].id + ) return make_response(jsonify(active_task_assigned_to_me), 200) +def task_show_completed_user_task( + process_instance_id: int, spiffworkflow_task_id: str +) -> flask.wrappers.Response: + """Task_show_completed_user_task.""" + process_instance = find_process_instance_by_id_or_raise(process_instance_id) + processor = ProcessInstanceProcessor(process_instance) + + if processor.completed_user_tasks() is None: + raise ( + ApiError( + code="no_completed_user_tasks", + message=f"This process instance does not have any completed user tasks: {process_instance_id}", + status_code=400, + ) + ) + + spiffworkflow_task = None + preceding_spiffworkflow_user_task_id = None + following_spiffworkflow_user_task_id = None + for index, completed_user_task in enumerate(processor.completed_user_tasks()): + if str(completed_user_task.id) == spiffworkflow_task_id: + spiffworkflow_task = completed_user_task + preceding_spiffworkflow_user_task_id = get_value_from_array_with_index( + processor.completed_user_tasks(), index + 1 + ) + following_spiffworkflow_user_task_id = get_value_from_array_with_index( + processor.completed_user_tasks(), index - 1 + ) + + if spiffworkflow_task is None: + raise ( + ApiError( + code="no_completed_user_task_with_id", + message=f"This process instance does not have a completed user task with given id: {spiffworkflow_task_id}", + status_code=400, + ) + ) + + process_model = get_process_model( + process_instance.process_model_identifier, + process_instance.process_group_identifier, + ) + + task = ProcessInstanceService.spiff_task_to_api_task( + spiffworkflow_task, add_docs_and_forms=True + ) + + form_contents = prepare_form_data( + task.properties["properties"]["formJsonSchemaFilename"], + spiffworkflow_task.data, + process_model, + ) + if form_contents is not None: + task.form_schema = form_contents + + task.data = spiffworkflow_task.data + + if preceding_spiffworkflow_user_task_id: + task.preceding_spiffworkflow_user_task_id = ( + preceding_spiffworkflow_user_task_id.id + ) + + if following_spiffworkflow_user_task_id: + task.following_spiffworkflow_user_task_id = ( + following_spiffworkflow_user_task_id.id + ) + + principal = find_principal_or_raise() + active_task = ( + ActiveTaskModel.query.filter_by( + assigned_principal_id=principal.id, process_instance_id=process_instance_id + ).order_by( + desc(ActiveTaskModel.id) + ) # type: ignore + ).first() + + task.current_active_task_id = active_task.id + + return Response( + json.dumps(TaskSchema().dump(task)), status=200, mimetype="application/json" + ) + + def task_submit_user_data( - task_id: int, body: Dict[str, Any], terminate_loop: bool = False + active_task_id: int, body: Dict[str, Any], terminate_loop: bool = False ) -> flask.wrappers.Response: """Task_submit_user_data.""" principal = find_principal_or_raise() - active_task_assigned_to_me = find_active_task_by_id_or_raise(task_id, principal.id) + active_task_assigned_to_me = find_active_task_by_id_or_raise( + active_task_id, principal.id + ) process_instance = find_process_instance_by_id_or_raise( active_task_assigned_to_me.process_instance_id @@ -701,17 +789,17 @@ def find_principal_or_raise() -> PrincipalModel: def find_active_task_by_id_or_raise( - task_id: int, principal_id: PrincipalModel + active_task_id: int, principal_id: PrincipalModel ) -> ActiveTaskModel: """Find_active_task_by_id_or_raise.""" active_task_assigned_to_me = ActiveTaskModel.query.filter_by( - id=task_id, assigned_principal_id=principal_id + id=active_task_id, assigned_principal_id=principal_id ).first() if active_task_assigned_to_me is None: raise ( ApiError( code="task_not_found", - message=f"Task not found for principal user: {principal_id} and id: {task_id}", + message=f"Task not found for principal user: {principal_id} and id: {active_task_id}", status_code=400, ) ) @@ -734,3 +822,28 @@ def find_process_instance_by_id_or_raise( ) ) return process_instance # type: ignore + + +def get_value_from_array_with_index(array: list, index: int) -> Any: + """Get_value_from_array_with_index.""" + if index < 0: + return None + + if index >= len(array): + return None + + return array[index] + + +def prepare_form_data( + form_file: str, spiffworkflow_data_json: dict, process_model: ProcessModelInfo +) -> str: + """Prepare_form_data.""" + file_contents = SpecFileService.get_data(process_model, form_file).decode("utf-8") + + # trade out pieces like "{{variable_name}}" for the corresponding form data value + for key, value in spiffworkflow_data_json.items(): + if isinstance(value, str) or isinstance(value, int): + file_contents = file_contents.replace("{{" + key + "}}", str(value)) + + return file_contents diff --git a/test.json b/test.json new file mode 100644 index 00000000..9eb0a3dc --- /dev/null +++ b/test.json @@ -0,0 +1 @@ +{"data": {"validate_only": false, "process_instance_id": 614}, "last_task": "2d449bc3-5825-49d5-8954-0e4aa965a41a", "success": true, "tasks": {"5cf148e9-8a18-4e30-b70a-0f379e3914f0": {"id": "5cf148e9-8a18-4e30-b70a-0f379e3914f0", "parent": null, "children": ["d77d94a6-9174-433b-95a9-09536f315cff"], "last_state_change": 1658326560.4419284, "state": 32, "task_spec": "Root", "triggered": false, "workflow_name": "test_form", "internal_data": {}, "data": {}}, "d77d94a6-9174-433b-95a9-09536f315cff": {"id": "d77d94a6-9174-433b-95a9-09536f315cff", "parent": "5cf148e9-8a18-4e30-b70a-0f379e3914f0", "children": ["82a5f501-dad6-4b1f-b6db-fdc1900ce8a5"], "last_state_change": 1658326560.4565284, "state": 32, "task_spec": "Start", "triggered": false, "workflow_name": "test_form", "internal_data": {}, "data": {"current_user": {"id": "1", "username": "test_user1"}}}, "82a5f501-dad6-4b1f-b6db-fdc1900ce8a5": {"id": "82a5f501-dad6-4b1f-b6db-fdc1900ce8a5", "parent": "d77d94a6-9174-433b-95a9-09536f315cff", "children": ["36f9305b-a50b-477a-bdf7-80ec8ae9fcd6"], "last_state_change": 1658326560.4569082, "state": 32, "task_spec": "StartEvent_1", "triggered": false, "workflow_name": "test_form", "internal_data": {"event_fired": true}, "data": {"current_user": {"id": "1", "username": "test_user1"}}}, "36f9305b-a50b-477a-bdf7-80ec8ae9fcd6": {"id": "36f9305b-a50b-477a-bdf7-80ec8ae9fcd6", "parent": "82a5f501-dad6-4b1f-b6db-fdc1900ce8a5", "children": ["b548f004-b536-41b2-b757-cc3d2b77bb1f"], "last_state_change": 1658326560.457242, "state": 32, "task_spec": "set_system_generated_number", "triggered": false, "workflow_name": "test_form", "internal_data": {}, "data": {"current_user": {"id": "1", "username": "test_user1"}, "system_generated_number": 4}}, "b548f004-b536-41b2-b757-cc3d2b77bb1f": {"id": "b548f004-b536-41b2-b757-cc3d2b77bb1f", "parent": "36f9305b-a50b-477a-bdf7-80ec8ae9fcd6", "children": ["2d449bc3-5825-49d5-8954-0e4aa965a41a"], "last_state_change": 1658326894.542517, "state": 32, "task_spec": "get_user_generated_number", "triggered": false, "workflow_name": "test_form", "internal_data": {}, "data": {"current_user": {"id": "1", "username": "test_user1"}, "system_generated_number": 4, "user_generated_number": 2}}, "2d449bc3-5825-49d5-8954-0e4aa965a41a": {"id": "2d449bc3-5825-49d5-8954-0e4aa965a41a", "parent": "b548f004-b536-41b2-b757-cc3d2b77bb1f", "children": ["e8890437-f835-4a70-97ae-017c203444e7"], "last_state_change": 1658326894.5578055, "state": 32, "task_spec": "multiply", "triggered": false, "workflow_name": "test_form", "internal_data": {}, "data": {"current_user": {"id": "1", "username": "test_user1"}, "system_generated_number": 4, "user_generated_number": 2, "product": 8}}, "e8890437-f835-4a70-97ae-017c203444e7": {"id": "e8890437-f835-4a70-97ae-017c203444e7", "parent": "2d449bc3-5825-49d5-8954-0e4aa965a41a", "children": ["cf0ddaf1-aee6-4393-aa48-5425a76f85f0"], "last_state_change": 1658326894.5580246, "state": 16, "task_spec": "Activity_05z7ccx", "triggered": false, "workflow_name": "test_form", "internal_data": {}, "data": {"current_user": {"id": "1", "username": "test_user1"}, "system_generated_number": 4, "user_generated_number": 2, "product": 8}}, "cf0ddaf1-aee6-4393-aa48-5425a76f85f0": {"id": "cf0ddaf1-aee6-4393-aa48-5425a76f85f0", "parent": "e8890437-f835-4a70-97ae-017c203444e7", "children": ["310e155e-238b-4627-a228-10f302e39ae4"], "last_state_change": 1658326560.4422436, "state": 4, "task_spec": "Activity_00mekhp", "triggered": false, "workflow_name": "test_form", "internal_data": {}, "data": {}}, "310e155e-238b-4627-a228-10f302e39ae4": {"id": "310e155e-238b-4627-a228-10f302e39ae4", "parent": "cf0ddaf1-aee6-4393-aa48-5425a76f85f0", "children": ["250180b0-f8ac-4bf3-b1ed-d369ed0beba6"], "last_state_change": 1658326560.4422898, "state": 4, "task_spec": "EndEvent_0q4qzl9", "triggered": false, "workflow_name": "test_form", "internal_data": {}, "data": {}}, "250180b0-f8ac-4bf3-b1ed-d369ed0beba6": {"id": "250180b0-f8ac-4bf3-b1ed-d369ed0beba6", "parent": "310e155e-238b-4627-a228-10f302e39ae4", "children": ["bff8b7dc-f1f8-4345-a50d-fe07560083e4"], "last_state_change": 1658326560.4423366, "state": 4, "task_spec": "test_form.EndJoin", "triggered": false, "workflow_name": "test_form", "internal_data": {}, "data": {}}, "bff8b7dc-f1f8-4345-a50d-fe07560083e4": {"id": "bff8b7dc-f1f8-4345-a50d-fe07560083e4", "parent": "250180b0-f8ac-4bf3-b1ed-d369ed0beba6", "children": [], "last_state_change": 1658326560.4423747, "state": 4, "task_spec": "End", "triggered": false, "workflow_name": "test_form", "internal_data": {}, "data": {}}}, "root": "5cf148e9-8a18-4e30-b70a-0f379e3914f0", "spec": {"name": "test_form", "description": "Test Form", "file": "test_form.bpmn", "task_specs": {"Start": {"id": "test_form_1", "name": "Start", "description": "", "manual": false, "internal": false, "lookahead": 2, "inputs": [], "outputs": ["StartEvent_1"], "typename": "StartTask"}, "test_form.EndJoin": {"id": "test_form_2", "name": "test_form.EndJoin", "description": "", "manual": false, "internal": false, "lookahead": 2, "inputs": ["EndEvent_0q4qzl9"], "outputs": ["End"], "typename": "_EndJoin"}, "End": {"id": "test_form_3", "name": "End", "description": "", "manual": false, "internal": false, "lookahead": 2, "inputs": ["test_form.EndJoin"], "outputs": [], "typename": "Simple"}, "StartEvent_1": {"id": "test_form_4", "name": "StartEvent_1", "description": null, "manual": false, "internal": false, "lookahead": 2, "inputs": ["Start"], "outputs": ["set_system_generated_number"], "lane": null, "documentation": null, "loopTask": false, "position": {"x": 112.0, "y": 99.0}, "outgoing_sequence_flows": {"set_system_generated_number": {"id": "SequenceFlow_0lvudp8", "name": null, "documentation": null, "target_task_spec": "set_system_generated_number", "typename": "SequenceFlow"}}, "outgoing_sequence_flows_by_id": {"SequenceFlow_0lvudp8": {"id": "SequenceFlow_0lvudp8", "name": null, "documentation": null, "target_task_spec": "set_system_generated_number", "typename": "SequenceFlow"}}, "data_input_associations": [], "data_output_associations": [], "event_definition": {"internal": false, "external": false, "typename": "NoneEventDefinition"}, "typename": "StartEvent", "extensions": {}}, "set_system_generated_number": {"id": "test_form_5", "name": "set_system_generated_number", "description": "set_system_generated_number", "manual": false, "internal": false, "lookahead": 2, "inputs": ["StartEvent_1"], "outputs": ["get_user_generated_number"], "lane": null, "documentation": null, "loopTask": false, "position": {"x": 190.0, "y": 77.0}, "outgoing_sequence_flows": {"get_user_generated_number": {"id": "Flow_0kk2hzj", "name": null, "documentation": null, "target_task_spec": "get_user_generated_number", "typename": "SequenceFlow"}}, "outgoing_sequence_flows_by_id": {"Flow_0kk2hzj": {"id": "Flow_0kk2hzj", "name": null, "documentation": null, "target_task_spec": "get_user_generated_number", "typename": "SequenceFlow"}}, "data_input_associations": [], "data_output_associations": [], "script": "system_generated_number = 4", "typename": "ScriptTask", "extensions": {}}, "get_user_generated_number": {"id": "test_form_6", "name": "get_user_generated_number", "description": "", "manual": false, "internal": false, "lookahead": 2, "inputs": ["set_system_generated_number"], "outputs": ["multiply"], "lane": null, "documentation": null, "loopTask": false, "position": {"x": 320.0, "y": 77.0}, "outgoing_sequence_flows": {"multiply": {"id": "Flow_1cck1pb", "name": null, "documentation": null, "target_task_spec": "multiply", "typename": "SequenceFlow"}}, "outgoing_sequence_flows_by_id": {"Flow_1cck1pb": {"id": "Flow_1cck1pb", "name": null, "documentation": null, "target_task_spec": "multiply", "typename": "SequenceFlow"}}, "data_input_associations": [], "data_output_associations": [], "prescript": null, "postscript": null, "typename": "UserTask", "extensions": {"properties": {"formJsonSchemaFilename": "give_me_a_number_form.json"}}}, "multiply": {"id": "test_form_7", "name": "multiply", "description": "multiply", "manual": false, "internal": false, "lookahead": 2, "inputs": ["get_user_generated_number"], "outputs": ["Activity_05z7ccx"], "lane": null, "documentation": null, "loopTask": false, "position": {"x": 450.0, "y": 77.0}, "outgoing_sequence_flows": {"Activity_05z7ccx": {"id": "Flow_16gxvwr", "name": null, "documentation": null, "target_task_spec": "Activity_05z7ccx", "typename": "SequenceFlow"}}, "outgoing_sequence_flows_by_id": {"Flow_16gxvwr": {"id": "Flow_16gxvwr", "name": null, "documentation": null, "target_task_spec": "Activity_05z7ccx", "typename": "SequenceFlow"}}, "data_input_associations": [], "data_output_associations": [], "script": "product = system_generated_number * user_generated_number", "typename": "ScriptTask", "extensions": {}}, "Activity_05z7ccx": {"id": "test_form_8", "name": "Activity_05z7ccx", "description": "", "manual": false, "internal": false, "lookahead": 2, "inputs": ["multiply"], "outputs": ["Activity_00mekhp"], "lane": null, "documentation": null, "loopTask": false, "position": {"x": 580.0, "y": 77.0}, "outgoing_sequence_flows": {"Activity_00mekhp": {"id": "Flow_0k1q81g", "name": null, "documentation": null, "target_task_spec": "Activity_00mekhp", "typename": "SequenceFlow"}}, "outgoing_sequence_flows_by_id": {"Flow_0k1q81g": {"id": "Flow_0k1q81g", "name": null, "documentation": null, "target_task_spec": "Activity_00mekhp", "typename": "SequenceFlow"}}, "data_input_associations": [], "data_output_associations": [], "prescript": null, "postscript": null, "typename": "UserTask", "extensions": {"properties": {"formJsonSchemaFilename": "give_me_another_number_form.json"}}}, "Activity_00mekhp": {"id": "test_form_9", "name": "Activity_00mekhp", "description": "multiply", "manual": false, "internal": false, "lookahead": 2, "inputs": ["Activity_05z7ccx"], "outputs": ["EndEvent_0q4qzl9"], "lane": null, "documentation": null, "loopTask": false, "position": {"x": 730.0, "y": 77.0}, "outgoing_sequence_flows": {"EndEvent_0q4qzl9": {"id": "Flow_1hp8s94", "name": null, "documentation": null, "target_task_spec": "EndEvent_0q4qzl9", "typename": "SequenceFlow"}}, "outgoing_sequence_flows_by_id": {"Flow_1hp8s94": {"id": "Flow_1hp8s94", "name": null, "documentation": null, "target_task_spec": "EndEvent_0q4qzl9", "typename": "SequenceFlow"}}, "data_input_associations": [], "data_output_associations": [], "script": "final_product = product * second_user_generated_number", "typename": "ScriptTask", "extensions": {}}, "EndEvent_0q4qzl9": {"id": "test_form_10", "name": "EndEvent_0q4qzl9", "description": null, "manual": false, "internal": false, "lookahead": 2, "inputs": ["Activity_00mekhp"], "outputs": ["test_form.EndJoin"], "lane": null, "documentation": null, "loopTask": false, "position": {"x": 862.0, "y": 99.0}, "outgoing_sequence_flows": {"test_form.EndJoin": {"id": "EndEvent_0q4qzl9.ToEndJoin", "name": null, "documentation": null, "target_task_spec": "test_form.EndJoin", "typename": "SequenceFlow"}}, "outgoing_sequence_flows_by_id": {"EndEvent_0q4qzl9.ToEndJoin": {"id": "EndEvent_0q4qzl9.ToEndJoin", "name": null, "documentation": null, "target_task_spec": "test_form.EndJoin", "typename": "SequenceFlow"}}, "data_input_associations": [], "data_output_associations": [], "event_definition": {"internal": false, "external": false, "typename": "NoneEventDefinition"}, "typename": "EndEvent", "extensions": {}}, "Root": {"id": "test_form_11", "name": "Root", "description": "", "manual": false, "internal": false, "lookahead": 2, "inputs": [], "outputs": [], "typename": "Simple"}}, "data_inputs": [], "data_outputs": [], "data_objects": [], "typename": "BpmnProcessSpec"}, "subprocess_specs": {}, "subprocesses": {}, "serializer_version": "1.0-CRC"} diff --git a/test2.json b/test2.json new file mode 100644 index 00000000..12429e62 --- /dev/null +++ b/test2.json @@ -0,0 +1,596 @@ +{ + "data": { + "validate_only": false, + "process_instance_id": 614 + }, + "last_task": "2d449bc3-5825-49d5-8954-0e4aa965a41a", + "success": true, + "tasks": { + "5cf148e9-8a18-4e30-b70a-0f379e3914f0": { + "id": "5cf148e9-8a18-4e30-b70a-0f379e3914f0", + "parent": null, + "children": [ + "d77d94a6-9174-433b-95a9-09536f315cff" + ], + "last_state_change": 1658326560.4419284, + "state": 32, + "task_spec": "Root", + "triggered": false, + "workflow_name": "test_form", + "internal_data": {}, + "data": {} + }, + "d77d94a6-9174-433b-95a9-09536f315cff": { + "id": "d77d94a6-9174-433b-95a9-09536f315cff", + "parent": "5cf148e9-8a18-4e30-b70a-0f379e3914f0", + "children": [ + "82a5f501-dad6-4b1f-b6db-fdc1900ce8a5" + ], + "last_state_change": 1658326560.4565284, + "state": 32, + "task_spec": "Start", + "triggered": false, + "workflow_name": "test_form", + "internal_data": {}, + "data": { + "current_user": { + "id": "1", + "username": "test_user1" + } + } + }, + "82a5f501-dad6-4b1f-b6db-fdc1900ce8a5": { + "id": "82a5f501-dad6-4b1f-b6db-fdc1900ce8a5", + "parent": "d77d94a6-9174-433b-95a9-09536f315cff", + "children": [ + "36f9305b-a50b-477a-bdf7-80ec8ae9fcd6" + ], + "last_state_change": 1658326560.4569082, + "state": 32, + "task_spec": "StartEvent_1", + "triggered": false, + "workflow_name": "test_form", + "internal_data": { + "event_fired": true + }, + "data": { + "current_user": { + "id": "1", + "username": "test_user1" + } + } + }, + "36f9305b-a50b-477a-bdf7-80ec8ae9fcd6": { + "id": "36f9305b-a50b-477a-bdf7-80ec8ae9fcd6", + "parent": "82a5f501-dad6-4b1f-b6db-fdc1900ce8a5", + "children": [ + "b548f004-b536-41b2-b757-cc3d2b77bb1f" + ], + "last_state_change": 1658326560.457242, + "state": 32, + "task_spec": "set_system_generated_number", + "triggered": false, + "workflow_name": "test_form", + "internal_data": {}, + "data": { + "current_user": { + "id": "1", + "username": "test_user1" + }, + "system_generated_number": 4 + } + }, + "b548f004-b536-41b2-b757-cc3d2b77bb1f": { + "id": "b548f004-b536-41b2-b757-cc3d2b77bb1f", + "parent": "36f9305b-a50b-477a-bdf7-80ec8ae9fcd6", + "children": [ + "2d449bc3-5825-49d5-8954-0e4aa965a41a" + ], + "last_state_change": 1658326894.542517, + "state": 32, + "task_spec": "get_user_generated_number", + "triggered": false, + "workflow_name": "test_form", + "internal_data": {}, + "data": { + "current_user": { + "id": "1", + "username": "test_user1" + }, + "system_generated_number": 4, + "user_generated_number": 2 + } + }, + "2d449bc3-5825-49d5-8954-0e4aa965a41a": { + "id": "2d449bc3-5825-49d5-8954-0e4aa965a41a", + "parent": "b548f004-b536-41b2-b757-cc3d2b77bb1f", + "children": [ + "e8890437-f835-4a70-97ae-017c203444e7" + ], + "last_state_change": 1658326894.5578055, + "state": 32, + "task_spec": "multiply", + "triggered": false, + "workflow_name": "test_form", + "internal_data": {}, + "data": { + "current_user": { + "id": "1", + "username": "test_user1" + }, + "system_generated_number": 4, + "user_generated_number": 2, + "product": 8 + } + }, + "e8890437-f835-4a70-97ae-017c203444e7": { + "id": "e8890437-f835-4a70-97ae-017c203444e7", + "parent": "2d449bc3-5825-49d5-8954-0e4aa965a41a", + "children": [ + "cf0ddaf1-aee6-4393-aa48-5425a76f85f0" + ], + "last_state_change": 1658326894.5580246, + "state": 16, + "task_spec": "Activity_05z7ccx", + "triggered": false, + "workflow_name": "test_form", + "internal_data": {}, + "data": { + "current_user": { + "id": "1", + "username": "test_user1" + }, + "system_generated_number": 4, + "user_generated_number": 2, + "product": 8 + } + }, + "cf0ddaf1-aee6-4393-aa48-5425a76f85f0": { + "id": "cf0ddaf1-aee6-4393-aa48-5425a76f85f0", + "parent": "e8890437-f835-4a70-97ae-017c203444e7", + "children": [ + "310e155e-238b-4627-a228-10f302e39ae4" + ], + "last_state_change": 1658326560.4422436, + "state": 4, + "task_spec": "Activity_00mekhp", + "triggered": false, + "workflow_name": "test_form", + "internal_data": {}, + "data": {} + }, + "310e155e-238b-4627-a228-10f302e39ae4": { + "id": "310e155e-238b-4627-a228-10f302e39ae4", + "parent": "cf0ddaf1-aee6-4393-aa48-5425a76f85f0", + "children": [ + "250180b0-f8ac-4bf3-b1ed-d369ed0beba6" + ], + "last_state_change": 1658326560.4422898, + "state": 4, + "task_spec": "EndEvent_0q4qzl9", + "triggered": false, + "workflow_name": "test_form", + "internal_data": {}, + "data": {} + }, + "250180b0-f8ac-4bf3-b1ed-d369ed0beba6": { + "id": "250180b0-f8ac-4bf3-b1ed-d369ed0beba6", + "parent": "310e155e-238b-4627-a228-10f302e39ae4", + "children": [ + "bff8b7dc-f1f8-4345-a50d-fe07560083e4" + ], + "last_state_change": 1658326560.4423366, + "state": 4, + "task_spec": "test_form.EndJoin", + "triggered": false, + "workflow_name": "test_form", + "internal_data": {}, + "data": {} + }, + "bff8b7dc-f1f8-4345-a50d-fe07560083e4": { + "id": "bff8b7dc-f1f8-4345-a50d-fe07560083e4", + "parent": "250180b0-f8ac-4bf3-b1ed-d369ed0beba6", + "children": [], + "last_state_change": 1658326560.4423747, + "state": 4, + "task_spec": "End", + "triggered": false, + "workflow_name": "test_form", + "internal_data": {}, + "data": {} + } + }, + "root": "5cf148e9-8a18-4e30-b70a-0f379e3914f0", + "spec": { + "name": "test_form", + "description": "Test Form", + "file": "test_form.bpmn", + "task_specs": { + "Start": { + "id": "test_form_1", + "name": "Start", + "description": "", + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [], + "outputs": [ + "StartEvent_1" + ], + "typename": "StartTask" + }, + "test_form.EndJoin": { + "id": "test_form_2", + "name": "test_form.EndJoin", + "description": "", + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [ + "EndEvent_0q4qzl9" + ], + "outputs": [ + "End" + ], + "typename": "_EndJoin" + }, + "End": { + "id": "test_form_3", + "name": "End", + "description": "", + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [ + "test_form.EndJoin" + ], + "outputs": [], + "typename": "Simple" + }, + "StartEvent_1": { + "id": "test_form_4", + "name": "StartEvent_1", + "description": null, + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [ + "Start" + ], + "outputs": [ + "set_system_generated_number" + ], + "lane": null, + "documentation": null, + "loopTask": false, + "position": { + "x": 112, + "y": 99 + }, + "outgoing_sequence_flows": { + "set_system_generated_number": { + "id": "SequenceFlow_0lvudp8", + "name": null, + "documentation": null, + "target_task_spec": "set_system_generated_number", + "typename": "SequenceFlow" + } + }, + "outgoing_sequence_flows_by_id": { + "SequenceFlow_0lvudp8": { + "id": "SequenceFlow_0lvudp8", + "name": null, + "documentation": null, + "target_task_spec": "set_system_generated_number", + "typename": "SequenceFlow" + } + }, + "data_input_associations": [], + "data_output_associations": [], + "event_definition": { + "internal": false, + "external": false, + "typename": "NoneEventDefinition" + }, + "typename": "StartEvent", + "extensions": {} + }, + "set_system_generated_number": { + "id": "test_form_5", + "name": "set_system_generated_number", + "description": "set_system_generated_number", + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [ + "StartEvent_1" + ], + "outputs": [ + "get_user_generated_number" + ], + "lane": null, + "documentation": null, + "loopTask": false, + "position": { + "x": 190, + "y": 77 + }, + "outgoing_sequence_flows": { + "get_user_generated_number": { + "id": "Flow_0kk2hzj", + "name": null, + "documentation": null, + "target_task_spec": "get_user_generated_number", + "typename": "SequenceFlow" + } + }, + "outgoing_sequence_flows_by_id": { + "Flow_0kk2hzj": { + "id": "Flow_0kk2hzj", + "name": null, + "documentation": null, + "target_task_spec": "get_user_generated_number", + "typename": "SequenceFlow" + } + }, + "data_input_associations": [], + "data_output_associations": [], + "script": "system_generated_number = 4", + "typename": "ScriptTask", + "extensions": {} + }, + "get_user_generated_number": { + "id": "test_form_6", + "name": "get_user_generated_number", + "description": "", + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [ + "set_system_generated_number" + ], + "outputs": [ + "multiply" + ], + "lane": null, + "documentation": null, + "loopTask": false, + "position": { + "x": 320, + "y": 77 + }, + "outgoing_sequence_flows": { + "multiply": { + "id": "Flow_1cck1pb", + "name": null, + "documentation": null, + "target_task_spec": "multiply", + "typename": "SequenceFlow" + } + }, + "outgoing_sequence_flows_by_id": { + "Flow_1cck1pb": { + "id": "Flow_1cck1pb", + "name": null, + "documentation": null, + "target_task_spec": "multiply", + "typename": "SequenceFlow" + } + }, + "data_input_associations": [], + "data_output_associations": [], + "prescript": null, + "postscript": null, + "typename": "UserTask", + "extensions": { + "properties": { + "formJsonSchemaFilename": "give_me_a_number_form.json" + } + } + }, + "multiply": { + "id": "test_form_7", + "name": "multiply", + "description": "multiply", + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [ + "get_user_generated_number" + ], + "outputs": [ + "Activity_05z7ccx" + ], + "lane": null, + "documentation": null, + "loopTask": false, + "position": { + "x": 450, + "y": 77 + }, + "outgoing_sequence_flows": { + "Activity_05z7ccx": { + "id": "Flow_16gxvwr", + "name": null, + "documentation": null, + "target_task_spec": "Activity_05z7ccx", + "typename": "SequenceFlow" + } + }, + "outgoing_sequence_flows_by_id": { + "Flow_16gxvwr": { + "id": "Flow_16gxvwr", + "name": null, + "documentation": null, + "target_task_spec": "Activity_05z7ccx", + "typename": "SequenceFlow" + } + }, + "data_input_associations": [], + "data_output_associations": [], + "script": "product = system_generated_number * user_generated_number", + "typename": "ScriptTask", + "extensions": {} + }, + "Activity_05z7ccx": { + "id": "test_form_8", + "name": "Activity_05z7ccx", + "description": "", + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [ + "multiply" + ], + "outputs": [ + "Activity_00mekhp" + ], + "lane": null, + "documentation": null, + "loopTask": false, + "position": { + "x": 580, + "y": 77 + }, + "outgoing_sequence_flows": { + "Activity_00mekhp": { + "id": "Flow_0k1q81g", + "name": null, + "documentation": null, + "target_task_spec": "Activity_00mekhp", + "typename": "SequenceFlow" + } + }, + "outgoing_sequence_flows_by_id": { + "Flow_0k1q81g": { + "id": "Flow_0k1q81g", + "name": null, + "documentation": null, + "target_task_spec": "Activity_00mekhp", + "typename": "SequenceFlow" + } + }, + "data_input_associations": [], + "data_output_associations": [], + "prescript": null, + "postscript": null, + "typename": "UserTask", + "extensions": { + "properties": { + "formJsonSchemaFilename": "give_me_another_number_form.json" + } + } + }, + "Activity_00mekhp": { + "id": "test_form_9", + "name": "Activity_00mekhp", + "description": "multiply", + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [ + "Activity_05z7ccx" + ], + "outputs": [ + "EndEvent_0q4qzl9" + ], + "lane": null, + "documentation": null, + "loopTask": false, + "position": { + "x": 730, + "y": 77 + }, + "outgoing_sequence_flows": { + "EndEvent_0q4qzl9": { + "id": "Flow_1hp8s94", + "name": null, + "documentation": null, + "target_task_spec": "EndEvent_0q4qzl9", + "typename": "SequenceFlow" + } + }, + "outgoing_sequence_flows_by_id": { + "Flow_1hp8s94": { + "id": "Flow_1hp8s94", + "name": null, + "documentation": null, + "target_task_spec": "EndEvent_0q4qzl9", + "typename": "SequenceFlow" + } + }, + "data_input_associations": [], + "data_output_associations": [], + "script": "final_product = product * second_user_generated_number", + "typename": "ScriptTask", + "extensions": {} + }, + "EndEvent_0q4qzl9": { + "id": "test_form_10", + "name": "EndEvent_0q4qzl9", + "description": null, + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [ + "Activity_00mekhp" + ], + "outputs": [ + "test_form.EndJoin" + ], + "lane": null, + "documentation": null, + "loopTask": false, + "position": { + "x": 862, + "y": 99 + }, + "outgoing_sequence_flows": { + "test_form.EndJoin": { + "id": "EndEvent_0q4qzl9.ToEndJoin", + "name": null, + "documentation": null, + "target_task_spec": "test_form.EndJoin", + "typename": "SequenceFlow" + } + }, + "outgoing_sequence_flows_by_id": { + "EndEvent_0q4qzl9.ToEndJoin": { + "id": "EndEvent_0q4qzl9.ToEndJoin", + "name": null, + "documentation": null, + "target_task_spec": "test_form.EndJoin", + "typename": "SequenceFlow" + } + }, + "data_input_associations": [], + "data_output_associations": [], + "event_definition": { + "internal": false, + "external": false, + "typename": "NoneEventDefinition" + }, + "typename": "EndEvent", + "extensions": {} + }, + "Root": { + "id": "test_form_11", + "name": "Root", + "description": "", + "manual": false, + "internal": false, + "lookahead": 2, + "inputs": [], + "outputs": [], + "typename": "Simple" + } + }, + "data_inputs": [], + "data_outputs": [], + "data_objects": [], + "typename": "BpmnProcessSpec" + }, + "subprocess_specs": {}, + "subprocesses": {}, + "serializer_version": "1.0-CRC" +} From fb92d6714de5077e7093bb6107b32c1d9c840d81 Mon Sep 17 00:00:00 2001 From: jasquat Date: Wed, 20 Jul 2022 15:44:35 -0400 Subject: [PATCH 02/20] fixed mypy ignore comment and removed accidentally committed files --- .../routes/process_api_blueprint.py | 4 +- test.json | 1 - test2.json | 596 ------------------ 3 files changed, 2 insertions(+), 599 deletions(-) delete mode 100644 test.json delete mode 100644 test2.json diff --git a/src/spiffworkflow_backend/routes/process_api_blueprint.py b/src/spiffworkflow_backend/routes/process_api_blueprint.py index 24a6326d..26904bb7 100644 --- a/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -666,8 +666,8 @@ def task_show_completed_user_task( ActiveTaskModel.query.filter_by( assigned_principal_id=principal.id, process_instance_id=process_instance_id ).order_by( - desc(ActiveTaskModel.id) - ) # type: ignore + desc(ActiveTaskModel.id) # type: ignore + ) ).first() task.current_active_task_id = active_task.id diff --git a/test.json b/test.json deleted file mode 100644 index 9eb0a3dc..00000000 --- a/test.json +++ /dev/null @@ -1 +0,0 @@ -{"data": {"validate_only": false, "process_instance_id": 614}, "last_task": "2d449bc3-5825-49d5-8954-0e4aa965a41a", "success": true, "tasks": {"5cf148e9-8a18-4e30-b70a-0f379e3914f0": {"id": "5cf148e9-8a18-4e30-b70a-0f379e3914f0", "parent": null, "children": ["d77d94a6-9174-433b-95a9-09536f315cff"], "last_state_change": 1658326560.4419284, "state": 32, "task_spec": "Root", "triggered": false, "workflow_name": "test_form", "internal_data": {}, "data": {}}, "d77d94a6-9174-433b-95a9-09536f315cff": {"id": "d77d94a6-9174-433b-95a9-09536f315cff", "parent": "5cf148e9-8a18-4e30-b70a-0f379e3914f0", "children": ["82a5f501-dad6-4b1f-b6db-fdc1900ce8a5"], "last_state_change": 1658326560.4565284, "state": 32, "task_spec": "Start", "triggered": false, "workflow_name": "test_form", "internal_data": {}, "data": {"current_user": {"id": "1", "username": "test_user1"}}}, "82a5f501-dad6-4b1f-b6db-fdc1900ce8a5": {"id": "82a5f501-dad6-4b1f-b6db-fdc1900ce8a5", "parent": "d77d94a6-9174-433b-95a9-09536f315cff", "children": ["36f9305b-a50b-477a-bdf7-80ec8ae9fcd6"], "last_state_change": 1658326560.4569082, "state": 32, "task_spec": "StartEvent_1", "triggered": false, "workflow_name": "test_form", "internal_data": {"event_fired": true}, "data": {"current_user": {"id": "1", "username": "test_user1"}}}, "36f9305b-a50b-477a-bdf7-80ec8ae9fcd6": {"id": "36f9305b-a50b-477a-bdf7-80ec8ae9fcd6", "parent": "82a5f501-dad6-4b1f-b6db-fdc1900ce8a5", "children": ["b548f004-b536-41b2-b757-cc3d2b77bb1f"], "last_state_change": 1658326560.457242, "state": 32, "task_spec": "set_system_generated_number", "triggered": false, "workflow_name": "test_form", "internal_data": {}, "data": {"current_user": {"id": "1", "username": "test_user1"}, "system_generated_number": 4}}, "b548f004-b536-41b2-b757-cc3d2b77bb1f": {"id": "b548f004-b536-41b2-b757-cc3d2b77bb1f", "parent": "36f9305b-a50b-477a-bdf7-80ec8ae9fcd6", "children": ["2d449bc3-5825-49d5-8954-0e4aa965a41a"], "last_state_change": 1658326894.542517, "state": 32, "task_spec": "get_user_generated_number", "triggered": false, "workflow_name": "test_form", "internal_data": {}, "data": {"current_user": {"id": "1", "username": "test_user1"}, "system_generated_number": 4, "user_generated_number": 2}}, "2d449bc3-5825-49d5-8954-0e4aa965a41a": {"id": "2d449bc3-5825-49d5-8954-0e4aa965a41a", "parent": "b548f004-b536-41b2-b757-cc3d2b77bb1f", "children": ["e8890437-f835-4a70-97ae-017c203444e7"], "last_state_change": 1658326894.5578055, "state": 32, "task_spec": "multiply", "triggered": false, "workflow_name": "test_form", "internal_data": {}, "data": {"current_user": {"id": "1", "username": "test_user1"}, "system_generated_number": 4, "user_generated_number": 2, "product": 8}}, "e8890437-f835-4a70-97ae-017c203444e7": {"id": "e8890437-f835-4a70-97ae-017c203444e7", "parent": "2d449bc3-5825-49d5-8954-0e4aa965a41a", "children": ["cf0ddaf1-aee6-4393-aa48-5425a76f85f0"], "last_state_change": 1658326894.5580246, "state": 16, "task_spec": "Activity_05z7ccx", "triggered": false, "workflow_name": "test_form", "internal_data": {}, "data": {"current_user": {"id": "1", "username": "test_user1"}, "system_generated_number": 4, "user_generated_number": 2, "product": 8}}, "cf0ddaf1-aee6-4393-aa48-5425a76f85f0": {"id": "cf0ddaf1-aee6-4393-aa48-5425a76f85f0", "parent": "e8890437-f835-4a70-97ae-017c203444e7", "children": ["310e155e-238b-4627-a228-10f302e39ae4"], "last_state_change": 1658326560.4422436, "state": 4, "task_spec": "Activity_00mekhp", "triggered": false, "workflow_name": "test_form", "internal_data": {}, "data": {}}, "310e155e-238b-4627-a228-10f302e39ae4": {"id": "310e155e-238b-4627-a228-10f302e39ae4", "parent": "cf0ddaf1-aee6-4393-aa48-5425a76f85f0", "children": ["250180b0-f8ac-4bf3-b1ed-d369ed0beba6"], "last_state_change": 1658326560.4422898, "state": 4, "task_spec": "EndEvent_0q4qzl9", "triggered": false, "workflow_name": "test_form", "internal_data": {}, "data": {}}, "250180b0-f8ac-4bf3-b1ed-d369ed0beba6": {"id": "250180b0-f8ac-4bf3-b1ed-d369ed0beba6", "parent": "310e155e-238b-4627-a228-10f302e39ae4", "children": ["bff8b7dc-f1f8-4345-a50d-fe07560083e4"], "last_state_change": 1658326560.4423366, "state": 4, "task_spec": "test_form.EndJoin", "triggered": false, "workflow_name": "test_form", "internal_data": {}, "data": {}}, "bff8b7dc-f1f8-4345-a50d-fe07560083e4": {"id": "bff8b7dc-f1f8-4345-a50d-fe07560083e4", "parent": "250180b0-f8ac-4bf3-b1ed-d369ed0beba6", "children": [], "last_state_change": 1658326560.4423747, "state": 4, "task_spec": "End", "triggered": false, "workflow_name": "test_form", "internal_data": {}, "data": {}}}, "root": "5cf148e9-8a18-4e30-b70a-0f379e3914f0", "spec": {"name": "test_form", "description": "Test Form", "file": "test_form.bpmn", "task_specs": {"Start": {"id": "test_form_1", "name": "Start", "description": "", "manual": false, "internal": false, "lookahead": 2, "inputs": [], "outputs": ["StartEvent_1"], "typename": "StartTask"}, "test_form.EndJoin": {"id": "test_form_2", "name": "test_form.EndJoin", "description": "", "manual": false, "internal": false, "lookahead": 2, "inputs": ["EndEvent_0q4qzl9"], "outputs": ["End"], "typename": "_EndJoin"}, "End": {"id": "test_form_3", "name": "End", "description": "", "manual": false, "internal": false, "lookahead": 2, "inputs": ["test_form.EndJoin"], "outputs": [], "typename": "Simple"}, "StartEvent_1": {"id": "test_form_4", "name": "StartEvent_1", "description": null, "manual": false, "internal": false, "lookahead": 2, "inputs": ["Start"], "outputs": ["set_system_generated_number"], "lane": null, "documentation": null, "loopTask": false, "position": {"x": 112.0, "y": 99.0}, "outgoing_sequence_flows": {"set_system_generated_number": {"id": "SequenceFlow_0lvudp8", "name": null, "documentation": null, "target_task_spec": "set_system_generated_number", "typename": "SequenceFlow"}}, "outgoing_sequence_flows_by_id": {"SequenceFlow_0lvudp8": {"id": "SequenceFlow_0lvudp8", "name": null, "documentation": null, "target_task_spec": "set_system_generated_number", "typename": "SequenceFlow"}}, "data_input_associations": [], "data_output_associations": [], "event_definition": {"internal": false, "external": false, "typename": "NoneEventDefinition"}, "typename": "StartEvent", "extensions": {}}, "set_system_generated_number": {"id": "test_form_5", "name": "set_system_generated_number", "description": "set_system_generated_number", "manual": false, "internal": false, "lookahead": 2, "inputs": ["StartEvent_1"], "outputs": ["get_user_generated_number"], "lane": null, "documentation": null, "loopTask": false, "position": {"x": 190.0, "y": 77.0}, "outgoing_sequence_flows": {"get_user_generated_number": {"id": "Flow_0kk2hzj", "name": null, "documentation": null, "target_task_spec": "get_user_generated_number", "typename": "SequenceFlow"}}, "outgoing_sequence_flows_by_id": {"Flow_0kk2hzj": {"id": "Flow_0kk2hzj", "name": null, "documentation": null, "target_task_spec": "get_user_generated_number", "typename": "SequenceFlow"}}, "data_input_associations": [], "data_output_associations": [], "script": "system_generated_number = 4", "typename": "ScriptTask", "extensions": {}}, "get_user_generated_number": {"id": "test_form_6", "name": "get_user_generated_number", "description": "", "manual": false, "internal": false, "lookahead": 2, "inputs": ["set_system_generated_number"], "outputs": ["multiply"], "lane": null, "documentation": null, "loopTask": false, "position": {"x": 320.0, "y": 77.0}, "outgoing_sequence_flows": {"multiply": {"id": "Flow_1cck1pb", "name": null, "documentation": null, "target_task_spec": "multiply", "typename": "SequenceFlow"}}, "outgoing_sequence_flows_by_id": {"Flow_1cck1pb": {"id": "Flow_1cck1pb", "name": null, "documentation": null, "target_task_spec": "multiply", "typename": "SequenceFlow"}}, "data_input_associations": [], "data_output_associations": [], "prescript": null, "postscript": null, "typename": "UserTask", "extensions": {"properties": {"formJsonSchemaFilename": "give_me_a_number_form.json"}}}, "multiply": {"id": "test_form_7", "name": "multiply", "description": "multiply", "manual": false, "internal": false, "lookahead": 2, "inputs": ["get_user_generated_number"], "outputs": ["Activity_05z7ccx"], "lane": null, "documentation": null, "loopTask": false, "position": {"x": 450.0, "y": 77.0}, "outgoing_sequence_flows": {"Activity_05z7ccx": {"id": "Flow_16gxvwr", "name": null, "documentation": null, "target_task_spec": "Activity_05z7ccx", "typename": "SequenceFlow"}}, "outgoing_sequence_flows_by_id": {"Flow_16gxvwr": {"id": "Flow_16gxvwr", "name": null, "documentation": null, "target_task_spec": "Activity_05z7ccx", "typename": "SequenceFlow"}}, "data_input_associations": [], "data_output_associations": [], "script": "product = system_generated_number * user_generated_number", "typename": "ScriptTask", "extensions": {}}, "Activity_05z7ccx": {"id": "test_form_8", "name": "Activity_05z7ccx", "description": "", "manual": false, "internal": false, "lookahead": 2, "inputs": ["multiply"], "outputs": ["Activity_00mekhp"], "lane": null, "documentation": null, "loopTask": false, "position": {"x": 580.0, "y": 77.0}, "outgoing_sequence_flows": {"Activity_00mekhp": {"id": "Flow_0k1q81g", "name": null, "documentation": null, "target_task_spec": "Activity_00mekhp", "typename": "SequenceFlow"}}, "outgoing_sequence_flows_by_id": {"Flow_0k1q81g": {"id": "Flow_0k1q81g", "name": null, "documentation": null, "target_task_spec": "Activity_00mekhp", "typename": "SequenceFlow"}}, "data_input_associations": [], "data_output_associations": [], "prescript": null, "postscript": null, "typename": "UserTask", "extensions": {"properties": {"formJsonSchemaFilename": "give_me_another_number_form.json"}}}, "Activity_00mekhp": {"id": "test_form_9", "name": "Activity_00mekhp", "description": "multiply", "manual": false, "internal": false, "lookahead": 2, "inputs": ["Activity_05z7ccx"], "outputs": ["EndEvent_0q4qzl9"], "lane": null, "documentation": null, "loopTask": false, "position": {"x": 730.0, "y": 77.0}, "outgoing_sequence_flows": {"EndEvent_0q4qzl9": {"id": "Flow_1hp8s94", "name": null, "documentation": null, "target_task_spec": "EndEvent_0q4qzl9", "typename": "SequenceFlow"}}, "outgoing_sequence_flows_by_id": {"Flow_1hp8s94": {"id": "Flow_1hp8s94", "name": null, "documentation": null, "target_task_spec": "EndEvent_0q4qzl9", "typename": "SequenceFlow"}}, "data_input_associations": [], "data_output_associations": [], "script": "final_product = product * second_user_generated_number", "typename": "ScriptTask", "extensions": {}}, "EndEvent_0q4qzl9": {"id": "test_form_10", "name": "EndEvent_0q4qzl9", "description": null, "manual": false, "internal": false, "lookahead": 2, "inputs": ["Activity_00mekhp"], "outputs": ["test_form.EndJoin"], "lane": null, "documentation": null, "loopTask": false, "position": {"x": 862.0, "y": 99.0}, "outgoing_sequence_flows": {"test_form.EndJoin": {"id": "EndEvent_0q4qzl9.ToEndJoin", "name": null, "documentation": null, "target_task_spec": "test_form.EndJoin", "typename": "SequenceFlow"}}, "outgoing_sequence_flows_by_id": {"EndEvent_0q4qzl9.ToEndJoin": {"id": "EndEvent_0q4qzl9.ToEndJoin", "name": null, "documentation": null, "target_task_spec": "test_form.EndJoin", "typename": "SequenceFlow"}}, "data_input_associations": [], "data_output_associations": [], "event_definition": {"internal": false, "external": false, "typename": "NoneEventDefinition"}, "typename": "EndEvent", "extensions": {}}, "Root": {"id": "test_form_11", "name": "Root", "description": "", "manual": false, "internal": false, "lookahead": 2, "inputs": [], "outputs": [], "typename": "Simple"}}, "data_inputs": [], "data_outputs": [], "data_objects": [], "typename": "BpmnProcessSpec"}, "subprocess_specs": {}, "subprocesses": {}, "serializer_version": "1.0-CRC"} diff --git a/test2.json b/test2.json deleted file mode 100644 index 12429e62..00000000 --- a/test2.json +++ /dev/null @@ -1,596 +0,0 @@ -{ - "data": { - "validate_only": false, - "process_instance_id": 614 - }, - "last_task": "2d449bc3-5825-49d5-8954-0e4aa965a41a", - "success": true, - "tasks": { - "5cf148e9-8a18-4e30-b70a-0f379e3914f0": { - "id": "5cf148e9-8a18-4e30-b70a-0f379e3914f0", - "parent": null, - "children": [ - "d77d94a6-9174-433b-95a9-09536f315cff" - ], - "last_state_change": 1658326560.4419284, - "state": 32, - "task_spec": "Root", - "triggered": false, - "workflow_name": "test_form", - "internal_data": {}, - "data": {} - }, - "d77d94a6-9174-433b-95a9-09536f315cff": { - "id": "d77d94a6-9174-433b-95a9-09536f315cff", - "parent": "5cf148e9-8a18-4e30-b70a-0f379e3914f0", - "children": [ - "82a5f501-dad6-4b1f-b6db-fdc1900ce8a5" - ], - "last_state_change": 1658326560.4565284, - "state": 32, - "task_spec": "Start", - "triggered": false, - "workflow_name": "test_form", - "internal_data": {}, - "data": { - "current_user": { - "id": "1", - "username": "test_user1" - } - } - }, - "82a5f501-dad6-4b1f-b6db-fdc1900ce8a5": { - "id": "82a5f501-dad6-4b1f-b6db-fdc1900ce8a5", - "parent": "d77d94a6-9174-433b-95a9-09536f315cff", - "children": [ - "36f9305b-a50b-477a-bdf7-80ec8ae9fcd6" - ], - "last_state_change": 1658326560.4569082, - "state": 32, - "task_spec": "StartEvent_1", - "triggered": false, - "workflow_name": "test_form", - "internal_data": { - "event_fired": true - }, - "data": { - "current_user": { - "id": "1", - "username": "test_user1" - } - } - }, - "36f9305b-a50b-477a-bdf7-80ec8ae9fcd6": { - "id": "36f9305b-a50b-477a-bdf7-80ec8ae9fcd6", - "parent": "82a5f501-dad6-4b1f-b6db-fdc1900ce8a5", - "children": [ - "b548f004-b536-41b2-b757-cc3d2b77bb1f" - ], - "last_state_change": 1658326560.457242, - "state": 32, - "task_spec": "set_system_generated_number", - "triggered": false, - "workflow_name": "test_form", - "internal_data": {}, - "data": { - "current_user": { - "id": "1", - "username": "test_user1" - }, - "system_generated_number": 4 - } - }, - "b548f004-b536-41b2-b757-cc3d2b77bb1f": { - "id": "b548f004-b536-41b2-b757-cc3d2b77bb1f", - "parent": "36f9305b-a50b-477a-bdf7-80ec8ae9fcd6", - "children": [ - "2d449bc3-5825-49d5-8954-0e4aa965a41a" - ], - "last_state_change": 1658326894.542517, - "state": 32, - "task_spec": "get_user_generated_number", - "triggered": false, - "workflow_name": "test_form", - "internal_data": {}, - "data": { - "current_user": { - "id": "1", - "username": "test_user1" - }, - "system_generated_number": 4, - "user_generated_number": 2 - } - }, - "2d449bc3-5825-49d5-8954-0e4aa965a41a": { - "id": "2d449bc3-5825-49d5-8954-0e4aa965a41a", - "parent": "b548f004-b536-41b2-b757-cc3d2b77bb1f", - "children": [ - "e8890437-f835-4a70-97ae-017c203444e7" - ], - "last_state_change": 1658326894.5578055, - "state": 32, - "task_spec": "multiply", - "triggered": false, - "workflow_name": "test_form", - "internal_data": {}, - "data": { - "current_user": { - "id": "1", - "username": "test_user1" - }, - "system_generated_number": 4, - "user_generated_number": 2, - "product": 8 - } - }, - "e8890437-f835-4a70-97ae-017c203444e7": { - "id": "e8890437-f835-4a70-97ae-017c203444e7", - "parent": "2d449bc3-5825-49d5-8954-0e4aa965a41a", - "children": [ - "cf0ddaf1-aee6-4393-aa48-5425a76f85f0" - ], - "last_state_change": 1658326894.5580246, - "state": 16, - "task_spec": "Activity_05z7ccx", - "triggered": false, - "workflow_name": "test_form", - "internal_data": {}, - "data": { - "current_user": { - "id": "1", - "username": "test_user1" - }, - "system_generated_number": 4, - "user_generated_number": 2, - "product": 8 - } - }, - "cf0ddaf1-aee6-4393-aa48-5425a76f85f0": { - "id": "cf0ddaf1-aee6-4393-aa48-5425a76f85f0", - "parent": "e8890437-f835-4a70-97ae-017c203444e7", - "children": [ - "310e155e-238b-4627-a228-10f302e39ae4" - ], - "last_state_change": 1658326560.4422436, - "state": 4, - "task_spec": "Activity_00mekhp", - "triggered": false, - "workflow_name": "test_form", - "internal_data": {}, - "data": {} - }, - "310e155e-238b-4627-a228-10f302e39ae4": { - "id": "310e155e-238b-4627-a228-10f302e39ae4", - "parent": "cf0ddaf1-aee6-4393-aa48-5425a76f85f0", - "children": [ - "250180b0-f8ac-4bf3-b1ed-d369ed0beba6" - ], - "last_state_change": 1658326560.4422898, - "state": 4, - "task_spec": "EndEvent_0q4qzl9", - "triggered": false, - "workflow_name": "test_form", - "internal_data": {}, - "data": {} - }, - "250180b0-f8ac-4bf3-b1ed-d369ed0beba6": { - "id": "250180b0-f8ac-4bf3-b1ed-d369ed0beba6", - "parent": "310e155e-238b-4627-a228-10f302e39ae4", - "children": [ - "bff8b7dc-f1f8-4345-a50d-fe07560083e4" - ], - "last_state_change": 1658326560.4423366, - "state": 4, - "task_spec": "test_form.EndJoin", - "triggered": false, - "workflow_name": "test_form", - "internal_data": {}, - "data": {} - }, - "bff8b7dc-f1f8-4345-a50d-fe07560083e4": { - "id": "bff8b7dc-f1f8-4345-a50d-fe07560083e4", - "parent": "250180b0-f8ac-4bf3-b1ed-d369ed0beba6", - "children": [], - "last_state_change": 1658326560.4423747, - "state": 4, - "task_spec": "End", - "triggered": false, - "workflow_name": "test_form", - "internal_data": {}, - "data": {} - } - }, - "root": "5cf148e9-8a18-4e30-b70a-0f379e3914f0", - "spec": { - "name": "test_form", - "description": "Test Form", - "file": "test_form.bpmn", - "task_specs": { - "Start": { - "id": "test_form_1", - "name": "Start", - "description": "", - "manual": false, - "internal": false, - "lookahead": 2, - "inputs": [], - "outputs": [ - "StartEvent_1" - ], - "typename": "StartTask" - }, - "test_form.EndJoin": { - "id": "test_form_2", - "name": "test_form.EndJoin", - "description": "", - "manual": false, - "internal": false, - "lookahead": 2, - "inputs": [ - "EndEvent_0q4qzl9" - ], - "outputs": [ - "End" - ], - "typename": "_EndJoin" - }, - "End": { - "id": "test_form_3", - "name": "End", - "description": "", - "manual": false, - "internal": false, - "lookahead": 2, - "inputs": [ - "test_form.EndJoin" - ], - "outputs": [], - "typename": "Simple" - }, - "StartEvent_1": { - "id": "test_form_4", - "name": "StartEvent_1", - "description": null, - "manual": false, - "internal": false, - "lookahead": 2, - "inputs": [ - "Start" - ], - "outputs": [ - "set_system_generated_number" - ], - "lane": null, - "documentation": null, - "loopTask": false, - "position": { - "x": 112, - "y": 99 - }, - "outgoing_sequence_flows": { - "set_system_generated_number": { - "id": "SequenceFlow_0lvudp8", - "name": null, - "documentation": null, - "target_task_spec": "set_system_generated_number", - "typename": "SequenceFlow" - } - }, - "outgoing_sequence_flows_by_id": { - "SequenceFlow_0lvudp8": { - "id": "SequenceFlow_0lvudp8", - "name": null, - "documentation": null, - "target_task_spec": "set_system_generated_number", - "typename": "SequenceFlow" - } - }, - "data_input_associations": [], - "data_output_associations": [], - "event_definition": { - "internal": false, - "external": false, - "typename": "NoneEventDefinition" - }, - "typename": "StartEvent", - "extensions": {} - }, - "set_system_generated_number": { - "id": "test_form_5", - "name": "set_system_generated_number", - "description": "set_system_generated_number", - "manual": false, - "internal": false, - "lookahead": 2, - "inputs": [ - "StartEvent_1" - ], - "outputs": [ - "get_user_generated_number" - ], - "lane": null, - "documentation": null, - "loopTask": false, - "position": { - "x": 190, - "y": 77 - }, - "outgoing_sequence_flows": { - "get_user_generated_number": { - "id": "Flow_0kk2hzj", - "name": null, - "documentation": null, - "target_task_spec": "get_user_generated_number", - "typename": "SequenceFlow" - } - }, - "outgoing_sequence_flows_by_id": { - "Flow_0kk2hzj": { - "id": "Flow_0kk2hzj", - "name": null, - "documentation": null, - "target_task_spec": "get_user_generated_number", - "typename": "SequenceFlow" - } - }, - "data_input_associations": [], - "data_output_associations": [], - "script": "system_generated_number = 4", - "typename": "ScriptTask", - "extensions": {} - }, - "get_user_generated_number": { - "id": "test_form_6", - "name": "get_user_generated_number", - "description": "", - "manual": false, - "internal": false, - "lookahead": 2, - "inputs": [ - "set_system_generated_number" - ], - "outputs": [ - "multiply" - ], - "lane": null, - "documentation": null, - "loopTask": false, - "position": { - "x": 320, - "y": 77 - }, - "outgoing_sequence_flows": { - "multiply": { - "id": "Flow_1cck1pb", - "name": null, - "documentation": null, - "target_task_spec": "multiply", - "typename": "SequenceFlow" - } - }, - "outgoing_sequence_flows_by_id": { - "Flow_1cck1pb": { - "id": "Flow_1cck1pb", - "name": null, - "documentation": null, - "target_task_spec": "multiply", - "typename": "SequenceFlow" - } - }, - "data_input_associations": [], - "data_output_associations": [], - "prescript": null, - "postscript": null, - "typename": "UserTask", - "extensions": { - "properties": { - "formJsonSchemaFilename": "give_me_a_number_form.json" - } - } - }, - "multiply": { - "id": "test_form_7", - "name": "multiply", - "description": "multiply", - "manual": false, - "internal": false, - "lookahead": 2, - "inputs": [ - "get_user_generated_number" - ], - "outputs": [ - "Activity_05z7ccx" - ], - "lane": null, - "documentation": null, - "loopTask": false, - "position": { - "x": 450, - "y": 77 - }, - "outgoing_sequence_flows": { - "Activity_05z7ccx": { - "id": "Flow_16gxvwr", - "name": null, - "documentation": null, - "target_task_spec": "Activity_05z7ccx", - "typename": "SequenceFlow" - } - }, - "outgoing_sequence_flows_by_id": { - "Flow_16gxvwr": { - "id": "Flow_16gxvwr", - "name": null, - "documentation": null, - "target_task_spec": "Activity_05z7ccx", - "typename": "SequenceFlow" - } - }, - "data_input_associations": [], - "data_output_associations": [], - "script": "product = system_generated_number * user_generated_number", - "typename": "ScriptTask", - "extensions": {} - }, - "Activity_05z7ccx": { - "id": "test_form_8", - "name": "Activity_05z7ccx", - "description": "", - "manual": false, - "internal": false, - "lookahead": 2, - "inputs": [ - "multiply" - ], - "outputs": [ - "Activity_00mekhp" - ], - "lane": null, - "documentation": null, - "loopTask": false, - "position": { - "x": 580, - "y": 77 - }, - "outgoing_sequence_flows": { - "Activity_00mekhp": { - "id": "Flow_0k1q81g", - "name": null, - "documentation": null, - "target_task_spec": "Activity_00mekhp", - "typename": "SequenceFlow" - } - }, - "outgoing_sequence_flows_by_id": { - "Flow_0k1q81g": { - "id": "Flow_0k1q81g", - "name": null, - "documentation": null, - "target_task_spec": "Activity_00mekhp", - "typename": "SequenceFlow" - } - }, - "data_input_associations": [], - "data_output_associations": [], - "prescript": null, - "postscript": null, - "typename": "UserTask", - "extensions": { - "properties": { - "formJsonSchemaFilename": "give_me_another_number_form.json" - } - } - }, - "Activity_00mekhp": { - "id": "test_form_9", - "name": "Activity_00mekhp", - "description": "multiply", - "manual": false, - "internal": false, - "lookahead": 2, - "inputs": [ - "Activity_05z7ccx" - ], - "outputs": [ - "EndEvent_0q4qzl9" - ], - "lane": null, - "documentation": null, - "loopTask": false, - "position": { - "x": 730, - "y": 77 - }, - "outgoing_sequence_flows": { - "EndEvent_0q4qzl9": { - "id": "Flow_1hp8s94", - "name": null, - "documentation": null, - "target_task_spec": "EndEvent_0q4qzl9", - "typename": "SequenceFlow" - } - }, - "outgoing_sequence_flows_by_id": { - "Flow_1hp8s94": { - "id": "Flow_1hp8s94", - "name": null, - "documentation": null, - "target_task_spec": "EndEvent_0q4qzl9", - "typename": "SequenceFlow" - } - }, - "data_input_associations": [], - "data_output_associations": [], - "script": "final_product = product * second_user_generated_number", - "typename": "ScriptTask", - "extensions": {} - }, - "EndEvent_0q4qzl9": { - "id": "test_form_10", - "name": "EndEvent_0q4qzl9", - "description": null, - "manual": false, - "internal": false, - "lookahead": 2, - "inputs": [ - "Activity_00mekhp" - ], - "outputs": [ - "test_form.EndJoin" - ], - "lane": null, - "documentation": null, - "loopTask": false, - "position": { - "x": 862, - "y": 99 - }, - "outgoing_sequence_flows": { - "test_form.EndJoin": { - "id": "EndEvent_0q4qzl9.ToEndJoin", - "name": null, - "documentation": null, - "target_task_spec": "test_form.EndJoin", - "typename": "SequenceFlow" - } - }, - "outgoing_sequence_flows_by_id": { - "EndEvent_0q4qzl9.ToEndJoin": { - "id": "EndEvent_0q4qzl9.ToEndJoin", - "name": null, - "documentation": null, - "target_task_spec": "test_form.EndJoin", - "typename": "SequenceFlow" - } - }, - "data_input_associations": [], - "data_output_associations": [], - "event_definition": { - "internal": false, - "external": false, - "typename": "NoneEventDefinition" - }, - "typename": "EndEvent", - "extensions": {} - }, - "Root": { - "id": "test_form_11", - "name": "Root", - "description": "", - "manual": false, - "internal": false, - "lookahead": 2, - "inputs": [], - "outputs": [], - "typename": "Simple" - } - }, - "data_inputs": [], - "data_outputs": [], - "data_objects": [], - "typename": "BpmnProcessSpec" - }, - "subprocess_specs": {}, - "subprocesses": {}, - "serializer_version": "1.0-CRC" -} From ab46ba13ce2fb40ba84c9e640bfc5514d773ae66 Mon Sep 17 00:00:00 2001 From: jasquat Date: Thu, 21 Jul 2022 08:51:20 -0400 Subject: [PATCH 03/20] fixed some mypy issues --- src/spiffworkflow_backend/models/task.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/spiffworkflow_backend/models/task.py b/src/spiffworkflow_backend/models/task.py index dccbe9a1..19f45569 100644 --- a/src/spiffworkflow_backend/models/task.py +++ b/src/spiffworkflow_backend/models/task.py @@ -1,6 +1,6 @@ """Task.""" import enum -from typing import Any +from typing import Any, Union import marshmallow from marshmallow import Schema @@ -110,12 +110,12 @@ class Task: multi_instance_index: str, process_name: str, properties: dict, - process_instance_id: int | None = None, - form_schema: str | None = None, - form_ui_schema: str | None = None, - preceding_spiffworkflow_user_task_id: str | int | None = None, - following_spiffworkflow_user_task_id: str | int | None = None, - current_active_task_id: int | None = None, + process_instance_id: Union[int, None] = None, + form_schema: Union[str, None] = None, + form_ui_schema: Union[str, None] = None, + preceding_spiffworkflow_user_task_id: Union[str, int, None] = None, + following_spiffworkflow_user_task_id: Union[str, int, None] = None, + current_active_task_id: Union[int, None] = None, ): """__init__.""" self.id = id From 06cfa6fbb9f9dd8a88c40b784c3e815d39c8c486 Mon Sep 17 00:00:00 2001 From: jasquat Date: Thu, 21 Jul 2022 08:56:38 -0400 Subject: [PATCH 04/20] precommit --- src/spiffworkflow_backend/models/task.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/spiffworkflow_backend/models/task.py b/src/spiffworkflow_backend/models/task.py index 19f45569..89b1788f 100644 --- a/src/spiffworkflow_backend/models/task.py +++ b/src/spiffworkflow_backend/models/task.py @@ -1,6 +1,7 @@ """Task.""" import enum -from typing import Any, Union +from typing import Any +from typing import Union import marshmallow from marshmallow import Schema From bd99af9bb8d8832254af27d4b512c6a4280bfefe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 21 Jul 2022 20:48:40 +0000 Subject: [PATCH 05/20] Bump pip from 22.1.2 to 22.2 in /.github/workflows Bumps [pip](https://github.com/pypa/pip) from 22.1.2 to 22.2. - [Release notes](https://github.com/pypa/pip/releases) - [Changelog](https://github.com/pypa/pip/blob/main/NEWS.rst) - [Commits](https://github.com/pypa/pip/compare/22.1.2...22.2) --- updated-dependencies: - dependency-name: pip dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/constraints.txt b/.github/workflows/constraints.txt index e351201d..90aa9d15 100644 --- a/.github/workflows/constraints.txt +++ b/.github/workflows/constraints.txt @@ -1,4 +1,4 @@ -pip==22.1.2 +pip==22.2 nox==2022.1.7 nox-poetry==1.0.1 poetry==1.1.14 From 05f82d193dd6ceb9477d0297824949ca03d7aacb Mon Sep 17 00:00:00 2001 From: jasquat Date: Thu, 21 Jul 2022 16:57:45 -0400 Subject: [PATCH 06/20] added extra items to process instance so we can highlight the active task --- .../models/process_instance.py | 10 +++++++++ .../routes/process_api_blueprint.py | 22 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/spiffworkflow_backend/models/process_instance.py b/src/spiffworkflow_backend/models/process_instance.py index c59156b1..9b135a8f 100644 --- a/src/spiffworkflow_backend/models/process_instance.py +++ b/src/spiffworkflow_backend/models/process_instance.py @@ -100,10 +100,17 @@ class ProcessInstanceModel(SpiffworkflowBaseDBModel): status: str = db.Column(db.String(50)) data: dict | None = None + bpmn_xml_file_name: str | None = None + bpmn_xml_file_contents: bytes | None = None + spiffworkflow_active_task_id: str | None = None @property def serialized(self) -> dict[str, Any]: """Return object data in serializeable format.""" + local_bpmn_xml_file_contents = "" + if self.bpmn_xml_file_contents: + local_bpmn_xml_file_contents = self.bpmn_xml_file_contents.decode("utf-8") + return { "id": self.id, "process_model_identifier": self.process_model_identifier, @@ -114,6 +121,9 @@ class ProcessInstanceModel(SpiffworkflowBaseDBModel): "end_in_seconds": self.end_in_seconds, "process_initiator_id": self.process_initiator_id, "data": self.data, + "bpmn_xml_file_name": self.bpmn_xml_file_name, + "bpmn_xml_file_contents": local_bpmn_xml_file_contents, + "spiffworkflow_active_task_id": self.spiffworkflow_active_task_id, } @property diff --git a/src/spiffworkflow_backend/routes/process_api_blueprint.py b/src/spiffworkflow_backend/routes/process_api_blueprint.py index 26904bb7..ac8a1c25 100644 --- a/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -392,9 +392,31 @@ def process_instance_show( ) -> flask.wrappers.Response: """Create_process_instance.""" process_instance = find_process_instance_by_id_or_raise(process_instance_id) + process_model = get_process_model(process_model_id, process_group_id) + processor = ProcessInstanceProcessor(process_instance) process_instance.data = processor.get_data() + if process_model.primary_file_name: + bpmn_xml_file_contents = SpecFileService.get_data( + process_model, process_model.primary_file_name + ) + process_instance.bpmn_xml_file_name = process_model.primary_file_name + process_instance.bpmn_xml_file_contents = bpmn_xml_file_contents + + active_task = ( + ActiveTaskModel.query.filter_by( + process_instance_id=process_instance_id + ).order_by( + desc(ActiveTaskModel.id) # type: ignore + ) + ).first() + + if active_task: + process_instance.spiffworkflow_active_task_id = ( + active_task.spiffworkflow_task_id + ) + return make_response(jsonify(process_instance), 200) From 84f619b84a843eecde88cd0fb1a558313a3adb30 Mon Sep 17 00:00:00 2001 From: jasquat Date: Fri, 22 Jul 2022 10:26:24 -0400 Subject: [PATCH 07/20] removed config from instance config --- src/instance/config.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/instance/config.py b/src/instance/config.py index 7c254351..c78a091f 100644 --- a/src/instance/config.py +++ b/src/instance/config.py @@ -1,2 +1 @@ """Config.""" -BPMN_SPEC_ABSOLUTE_DIR = "BPMN_SPECS_DEV" From 0dbf729279ba1784afa2cc22dbdfd46ea4359ce4 Mon Sep 17 00:00:00 2001 From: jasquat Date: Fri, 22 Jul 2022 10:54:50 -0400 Subject: [PATCH 08/20] added some instructions to run locally --- README.rst | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/README.rst b/README.rst index 7929d870..12cab633 100644 --- a/README.rst +++ b/README.rst @@ -42,26 +42,27 @@ Features * Backend API portion of the spiffworkflow engine webapp +Running Locally +--------------- + +* Install libraries using poetry: + .. code:: console + $ poetry install + +* Setup the database - currently requires mysql: + .. code:: console + $ ./bin/recreate_db + +* Run the server: + .. code:: console + $ ./bin/run_server_locally + + Requirements ------------ * Python 3.9+ - - -Installation ------------- - -You can install *Spiffworkflow Backend* via pip_ from PyPI_: - -.. code:: console - - $ pip install spiffworkflow-backend - - -Usage ------ - -Please see the `Command-line Reference `_ for details. +* Poetry Contributing From 3130427c22610a51172f9ec31d9052fcb44fe132 Mon Sep 17 00:00:00 2001 From: jasquat Date: Fri, 22 Jul 2022 10:56:04 -0400 Subject: [PATCH 09/20] attempting to fix formatting --- README.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.rst b/README.rst index 12cab633..3e31a79c 100644 --- a/README.rst +++ b/README.rst @@ -46,16 +46,16 @@ Running Locally --------------- * Install libraries using poetry: - .. code:: console - $ poetry install +.. code:: console + $ poetry install * Setup the database - currently requires mysql: - .. code:: console - $ ./bin/recreate_db +.. code:: console + $ ./bin/recreate_db * Run the server: - .. code:: console - $ ./bin/run_server_locally +.. code:: console + $ ./bin/run_server_locally Requirements From 0773c8377d7d35c2e0f249c07e3f67d48c0a68c5 Mon Sep 17 00:00:00 2001 From: jasquat Date: Fri, 22 Jul 2022 11:00:34 -0400 Subject: [PATCH 10/20] attempting to fix formatting again --- README.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.rst b/README.rst index 3e31a79c..45ad1443 100644 --- a/README.rst +++ b/README.rst @@ -46,15 +46,21 @@ Running Locally --------------- * Install libraries using poetry: + .. code:: console + $ poetry install * Setup the database - currently requires mysql: + .. code:: console + $ ./bin/recreate_db * Run the server: + .. code:: console + $ ./bin/run_server_locally From f65228c87fb4c880ab5e2251a9e885a739d56335 Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 25 Jul 2022 11:48:42 -0400 Subject: [PATCH 11/20] some updates to always pass back task intead of active_task --- migrations/env.py | 2 + .../{3f7aa48eaf3a_.py => b4f678040235_.py} | 18 +++-- src/instance/config.py | 2 +- src/spiffworkflow_backend/api.yml | 64 ++++------------ .../models/active_task.py | 35 +++++++-- src/spiffworkflow_backend/models/task.py | 76 +++++++++++++------ .../routes/process_api_blueprint.py | 66 ++++++++++------ .../services/process_instance_processor.py | 16 ++-- .../services/process_instance_service.py | 11 +-- 9 files changed, 164 insertions(+), 126 deletions(-) rename migrations/versions/{3f7aa48eaf3a_.py => b4f678040235_.py} (93%) diff --git a/migrations/env.py b/migrations/env.py index 630e381a..68feded2 100644 --- a/migrations/env.py +++ b/migrations/env.py @@ -1,3 +1,5 @@ +from __future__ import with_statement + import logging from logging.config import fileConfig diff --git a/migrations/versions/3f7aa48eaf3a_.py b/migrations/versions/b4f678040235_.py similarity index 93% rename from migrations/versions/3f7aa48eaf3a_.py rename to migrations/versions/b4f678040235_.py index d3795dd6..efb50d48 100644 --- a/migrations/versions/3f7aa48eaf3a_.py +++ b/migrations/versions/b4f678040235_.py @@ -1,8 +1,8 @@ """empty message -Revision ID: 3f7aa48eaf3a +Revision ID: b4f678040235 Revises: -Create Date: 2022-07-11 16:08:00.002287 +Create Date: 2022-07-25 09:46:39.406847 """ from alembic import op @@ -10,7 +10,7 @@ import sqlalchemy as sa # revision identifiers, used by Alembic. -revision = '3f7aa48eaf3a' +revision = 'b4f678040235' down_revision = None branch_labels = None depends_on = None @@ -95,18 +95,22 @@ def upgrade(): ) op.create_table('active_task', sa.Column('id', sa.Integer(), nullable=False), - sa.Column('spiffworkflow_task_id', sa.String(length=50), nullable=False), sa.Column('process_instance_id', sa.Integer(), nullable=False), sa.Column('assigned_principal_id', sa.Integer(), nullable=True), - sa.Column('spiffworkflow_task_data', sa.Text(), nullable=True), - sa.Column('status', sa.String(length=20), nullable=False), sa.Column('form_file_name', sa.String(length=50), nullable=True), + sa.Column('ui_form_file_name', sa.String(length=50), nullable=True), sa.Column('updated_at_in_seconds', sa.Integer(), nullable=True), sa.Column('created_at_in_seconds', sa.Integer(), nullable=True), + sa.Column('task_id', sa.String(length=50), nullable=True), + sa.Column('task_name', sa.String(length=50), nullable=True), + sa.Column('task_title', sa.String(length=50), nullable=True), + sa.Column('task_type', sa.String(length=50), nullable=True), + sa.Column('task_status', sa.String(length=50), nullable=True), + sa.Column('task_data', sa.Text(), nullable=True), sa.ForeignKeyConstraint(['assigned_principal_id'], ['principal.id'], ), sa.ForeignKeyConstraint(['process_instance_id'], ['process_instance.id'], ), sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('spiffworkflow_task_id', 'process_instance_id', name='active_task_unique') + sa.UniqueConstraint('task_id', 'process_instance_id', name='active_task_unique') ) op.create_table('file', sa.Column('id', sa.Integer(), nullable=False), diff --git a/src/instance/config.py b/src/instance/config.py index 7c254351..9901d211 100644 --- a/src/instance/config.py +++ b/src/instance/config.py @@ -1,2 +1,2 @@ """Config.""" -BPMN_SPEC_ABSOLUTE_DIR = "BPMN_SPECS_DEV" +# BPMN_SPEC_ABSOLUTE_DIR = "BPMN_SPECS_DEV" diff --git a/src/spiffworkflow_backend/api.yml b/src/spiffworkflow_backend/api.yml index 05356176..86bab573 100755 --- a/src/spiffworkflow_backend/api.yml +++ b/src/spiffworkflow_backend/api.yml @@ -645,7 +645,7 @@ paths: # '204': # description: The file was removed. - /tasks/my-tasks: + /tasks: parameters: - name: page in: query @@ -670,53 +670,10 @@ paths: schema: type: array items: - # $ref: "#/components/schemas/ActiveTask" $ref: "#/components/schemas/Task" - /tasks/{active_task_id}: + /tasks/{process_instance_id}/{task_id}: parameters: - - name: active_task_id - in: path - required: true - description: The unique id of an existing process group. - schema: - type: string - get: - operationId: spiffworkflow_backend.routes.process_api_blueprint.task_show - summary: Gets one task that a user wants to complete - responses: - "200": - description: One task - content: - application/json: - schema: - $ref: "#/components/schemas/Task" - /tasks/completed_user_task/{process_instance_id}/{spiffworkflow_task_id}: - parameters: - - name: process_instance_id - in: path - required: true - description: The unique id of an existing process instance. - schema: - type: integer - - name: spiffworkflow_task_id - in: path - required: true - description: The unique id of an existing process group. - schema: - type: string - get: - operationId: spiffworkflow_backend.routes.process_api_blueprint.task_show_completed_user_task - summary: Gets one task that a user wants to complete - responses: - "200": - description: One task - content: - application/json: - schema: - $ref: "#/components/schemas/Task" - /tasks/{active_task_id}/submit: - parameters: - - name: active_task_id + - name: task_id in: path required: true description: The unique id of an existing process group. @@ -728,9 +685,18 @@ paths: description: Terminate the loop on a looping task schema: type: boolean - - post: - operationId: spiffworkflow_backend.routes.process_api_blueprint.task_submit_user_data + get: + operationId: spiffworkflow_backend.routes.process_api_blueprint.task_show + summary: Gets one task that a user wants to complete + responses: + "200": + description: One task + content: + application/json: + schema: + $ref: "#/components/schemas/Task" + put: + operationId: spiffworkflow_backend.routes.process_api_blueprint.task_submit summary: Update the form data for a tasks requestBody: content: diff --git a/src/spiffworkflow_backend/models/active_task.py b/src/spiffworkflow_backend/models/active_task.py index 113b9fc1..180b4358 100644 --- a/src/spiffworkflow_backend/models/active_task.py +++ b/src/spiffworkflow_backend/models/active_task.py @@ -1,6 +1,7 @@ """Active_task.""" from __future__ import annotations +import json from dataclasses import dataclass from flask_bpmn.models.db import db @@ -11,6 +12,7 @@ from sqlalchemy.orm import RelationshipProperty from spiffworkflow_backend.models.principal import PrincipalModel from spiffworkflow_backend.models.process_instance import ProcessInstanceModel +from spiffworkflow_backend.models.task import Task @dataclass @@ -20,26 +22,45 @@ class ActiveTaskModel(SpiffworkflowBaseDBModel): __tablename__ = "active_task" __table_args__ = ( db.UniqueConstraint( - "spiffworkflow_task_id", "process_instance_id", name="active_task_unique" + "task_id", "process_instance_id", name="active_task_unique" ), ) - form_json: str | None = "" - bpmn_json: str = "" - preceding_spiffworkflow_user_task_id: int | None = None + # form_json: str | None = "" + # bpmn_json: str = "" + # preceding_spiffworkflow_user_task_id: int | None = None assigned_principal: RelationshipProperty[PrincipalModel] = relationship( PrincipalModel ) id: int = db.Column(db.Integer, primary_key=True) - spiffworkflow_task_id: str = db.Column(db.String(50), nullable=False) process_instance_id: int = db.Column( ForeignKey(ProcessInstanceModel.id), nullable=False # type: ignore ) assigned_principal_id: int = db.Column(ForeignKey(PrincipalModel.id)) - spiffworkflow_task_data: str = db.Column(db.Text) - status: str = db.Column(db.String(20), nullable=False) form_file_name: str | None = db.Column(db.String(50)) + ui_form_file_name: str | None = db.Column(db.String(50)) updated_at_in_seconds: int = db.Column(db.Integer) created_at_in_seconds: int = db.Column(db.Integer) + + task_id = db.Column(db.String(50)) + task_name = db.Column(db.String(50)) + task_title = db.Column(db.String(50)) + task_type = db.Column(db.String(50)) + task_status = db.Column(db.String(50)) + task_data: str = db.Column(db.Text) + + def to_task(self) -> Task: + """To_task.""" + task_data = json.loads(self.task_data) + + return Task( + self.task_id, + self.task_name, + self.task_title, + self.task_type, + self.task_status, + data=task_data, + process_instance_id=self.process_instance_id, + ) diff --git a/src/spiffworkflow_backend/models/task.py b/src/spiffworkflow_backend/models/task.py index 89b1788f..d5f9201e 100644 --- a/src/spiffworkflow_backend/models/task.py +++ b/src/spiffworkflow_backend/models/task.py @@ -1,7 +1,6 @@ """Task.""" import enum from typing import Any -from typing import Union import marshmallow from marshmallow import Schema @@ -102,21 +101,21 @@ class Task: title: str, type: str, state: str, - lane: str, - form: None, - documentation: str, - data: dict[str, Any], - multi_instance_type: MultiInstanceType, - multi_instance_count: str, - multi_instance_index: str, - process_name: str, - properties: dict, - process_instance_id: Union[int, None] = None, - form_schema: Union[str, None] = None, - form_ui_schema: Union[str, None] = None, - preceding_spiffworkflow_user_task_id: Union[str, int, None] = None, - following_spiffworkflow_user_task_id: Union[str, int, None] = None, - current_active_task_id: Union[int, None] = None, + lane: str | None = None, + form: None = None, + documentation: str = "", + data: dict[str, Any] | None = None, + multi_instance_type: MultiInstanceType | None = None, + multi_instance_count: str = "", + multi_instance_index: str = "", + process_name: str = "", + properties: dict | None = None, + process_instance_id: int | None = None, + form_schema: str | None = None, + form_ui_schema: str | None = None, + # preceding_spiffworkflow_user_task_id: Union[str, int, None] = None, + # following_spiffworkflow_user_task_id: Union[str, int, None] = None, + # current_active_task_id: Union[int, None] = None, ): """__init__.""" self.id = id @@ -124,17 +123,20 @@ class Task: self.title = title self.type = type self.state = state - self.form = None + self.form = form self.documentation = documentation - self.data = data self.lane = lane + self.data = data + if self.data is None: + self.data = {} + self.process_instance_id = process_instance_id self.form_schema = form_schema self.form_ui_schema = form_ui_schema - self.preceding_spiffworkflow_user_task_id = preceding_spiffworkflow_user_task_id - self.following_spiffworkflow_user_task_id = following_spiffworkflow_user_task_id - self.current_active_task_id = current_active_task_id + # self.preceding_spiffworkflow_user_task_id = preceding_spiffworkflow_user_task_id + # self.following_spiffworkflow_user_task_id = following_spiffworkflow_user_task_id + # self.current_active_task_id = current_active_task_id self.multi_instance_type = ( multi_instance_type # Some tasks have a repeat behavior. @@ -146,7 +148,33 @@ class Task: multi_instance_index # And the index of the currently repeating task. ) self.process_name = process_name + self.properties = properties # Arbitrary extension properties from BPMN editor. + if self.properties is None: + self.properties = {} + + @property + def serialized(self) -> dict[str, Any]: + """Return object data in serializeable format.""" + return { + "id": self.id, + "name": self.name, + "title": self.title, + "type": self.type, + "state": self.state, + "lane": self.lane, + "form": self.form, + "documentation": self.documentation, + "data": self.data, + "multi_instance_type": self.multi_instance_type, + "multi_instance_count": self.multi_instance_count, + "multi_instance_index": self.multi_instance_index, + "process_name": self.process_name, + "properties": self.properties, + "process_instance_id": self.process_instance_id, + "form_schema": self.form_schema, + "form_ui_schema": self.form_ui_schema, + } @classmethod def valid_property_names(cls) -> list[str]: @@ -246,9 +274,9 @@ class TaskSchema(Schema): "process_instance_id", "form_schema", "form_ui_schema", - "preceding_spiffworkflow_user_task_id", - "following_spiffworkflow_user_task_id", - "current_active_task_id", + # "preceding_spiffworkflow_user_task_id", + # "following_spiffworkflow_user_task_id", + # "current_active_task_id", ] multi_instance_type = EnumField(MultiInstanceType) diff --git a/src/spiffworkflow_backend/routes/process_api_blueprint.py b/src/spiffworkflow_backend/routes/process_api_blueprint.py index 26904bb7..29ce0da7 100644 --- a/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -540,23 +540,26 @@ def task_list_my_tasks(page: int = 1, per_page: int = 100) -> flask.wrappers.Res .paginate(page, per_page, False) ) + tasks = [active_task.to_task() for active_task in active_tasks.items] + response_json = { - "results": active_tasks.items, + "results": tasks, "pagination": { "count": len(active_tasks.items), "total": active_tasks.total, "pages": active_tasks.pages, }, } + return make_response(jsonify(response_json), 200) -def task_show(active_task_id: int) -> flask.wrappers.Response: +def task_show(process_instance_id: int, task_id: str) -> flask.wrappers.Response: """Task_list_my_tasks.""" principal = find_principal_or_raise() active_task_assigned_to_me = find_active_task_by_id_or_raise( - active_task_id, principal.id + process_instance_id, task_id, principal.id ) process_instance = find_process_instance_by_id_or_raise( @@ -571,31 +574,35 @@ def task_show(active_task_id: int) -> flask.wrappers.Response: raise ( ApiError( code="missing_form_file", - message=f"Cannot find a form file for active task {active_task_id}", + message=f"Cannot find a form file for process_instance_id: {process_instance_id}, task_id: {task_id}", status_code=500, ) ) form_contents = prepare_form_data( active_task_assigned_to_me.form_file_name, - json.loads(active_task_assigned_to_me.spiffworkflow_task_data), + json.loads(active_task_assigned_to_me.task_data), process_model, ) + + task = active_task_assigned_to_me.to_task() if form_contents: - active_task_assigned_to_me.form_json = form_contents + task.form_schema = form_contents - # FIXME: This should be stored in the db when the active task is created - processor = ProcessInstanceProcessor(process_instance) - if processor.completed_user_tasks(): - active_task_assigned_to_me.preceding_spiffworkflow_user_task_id = ( - processor.completed_user_tasks()[0].id + if active_task_assigned_to_me.ui_form_file_name: + ui_form_contents = prepare_form_data( + active_task_assigned_to_me.ui_form_file_name, + json.loads(active_task_assigned_to_me.task_data), + process_model, ) + if ui_form_contents: + task.form_ui_schema = ui_form_contents - return make_response(jsonify(active_task_assigned_to_me), 200) + return make_response(jsonify(task), 200) def task_show_completed_user_task( - process_instance_id: int, spiffworkflow_task_id: str + process_instance_id: int, spiffworkflow_task_uuid: str ) -> flask.wrappers.Response: """Task_show_completed_user_task.""" process_instance = find_process_instance_by_id_or_raise(process_instance_id) @@ -614,7 +621,7 @@ def task_show_completed_user_task( preceding_spiffworkflow_user_task_id = None following_spiffworkflow_user_task_id = None for index, completed_user_task in enumerate(processor.completed_user_tasks()): - if str(completed_user_task.id) == spiffworkflow_task_id: + if str(completed_user_task.id) == spiffworkflow_task_uuid: spiffworkflow_task = completed_user_task preceding_spiffworkflow_user_task_id = get_value_from_array_with_index( processor.completed_user_tasks(), index + 1 @@ -627,7 +634,7 @@ def task_show_completed_user_task( raise ( ApiError( code="no_completed_user_task_with_id", - message=f"This process instance does not have a completed user task with given id: {spiffworkflow_task_id}", + message=f"This process instance does not have a completed user task with given id: {spiffworkflow_task_uuid}", status_code=400, ) ) @@ -677,13 +684,16 @@ def task_show_completed_user_task( ) -def task_submit_user_data( - active_task_id: int, body: Dict[str, Any], terminate_loop: bool = False +def task_submit( + process_instance_id: int, + task_id: str, + body: Dict[str, Any], + terminate_loop: bool = False, ) -> flask.wrappers.Response: """Task_submit_user_data.""" principal = find_principal_or_raise() active_task_assigned_to_me = find_active_task_by_id_or_raise( - active_task_id, principal.id + process_instance_id, task_id, principal.id ) process_instance = find_process_instance_by_id_or_raise( @@ -691,10 +701,10 @@ def task_submit_user_data( ) processor = ProcessInstanceProcessor(process_instance) - spiffworkflow_task_uuid = uuid.UUID( - active_task_assigned_to_me.spiffworkflow_task_id + task_uuid = uuid.UUID( + active_task_assigned_to_me.task_id ) - spiff_task = processor.bpmn_process_instance.get_task(spiffworkflow_task_uuid) + spiff_task = processor.bpmn_process_instance.get_task(task_uuid) if spiff_task is None: raise ( @@ -738,7 +748,7 @@ def task_submit_user_data( assigned_principal_id=principal.id, process_instance_id=process_instance.id ).first() if next_active_task_assigned_to_me: - return make_response(jsonify(next_active_task_assigned_to_me), 200) + return make_response(jsonify(next_active_task_assigned_to_me.to_task()), 200) return Response(json.dumps({"ok": True}), status=202, mimetype="application/json") @@ -789,17 +799,23 @@ def find_principal_or_raise() -> PrincipalModel: def find_active_task_by_id_or_raise( - active_task_id: int, principal_id: PrincipalModel + process_instance_id: int, task_id: str, principal_id: PrincipalModel ) -> ActiveTaskModel: """Find_active_task_by_id_or_raise.""" active_task_assigned_to_me = ActiveTaskModel.query.filter_by( - id=active_task_id, assigned_principal_id=principal_id + process_instance_id=process_instance_id, + task_id=task_id, + assigned_principal_id=principal_id, ).first() if active_task_assigned_to_me is None: + message = ( + f"Task not found for principal user {principal_id} " + f"process_instance_id: {process_instance_id}, task_id: {task_id}" + ) raise ( ApiError( code="task_not_found", - message=f"Task not found for principal user: {principal_id} and id: {active_task_id}", + message=message, status_code=400, ) ) diff --git a/src/spiffworkflow_backend/services/process_instance_processor.py b/src/spiffworkflow_backend/services/process_instance_processor.py index c633d519..59e804fd 100644 --- a/src/spiffworkflow_backend/services/process_instance_processor.py +++ b/src/spiffworkflow_backend/services/process_instance_processor.py @@ -355,22 +355,26 @@ class ProcessInstanceProcessor: extensions = ready_or_waiting_task.task_spec.extensions form_file_name = None + ui_form_file_name = None if "properties" in extensions: properties = extensions["properties"] if "formJsonSchemaFilename" in properties: form_file_name = properties["formJsonSchemaFilename"] - # FIXME: - # if "formUiSchemaFilename" in properties: - # form_file_name = properties["formUiSchemaFilename"] + if "formUiSchemaFilename" in properties: + ui_form_file_name = properties["formUiSchemaFilename"] active_task = ActiveTaskModel( - spiffworkflow_task_id=str(ready_or_waiting_task.id), process_instance_id=self.process_instance_model.id, # FIXME: look for the correct principal based on ready_or_waiting_task.lane assigned_principal_id=PrincipalModel.query.first().id, - spiffworkflow_task_data=json.dumps(ready_or_waiting_task.data), - status=ready_or_waiting_task.state.name, form_file_name=form_file_name, + ui_form_file_name=ui_form_file_name, + task_id=str(ready_or_waiting_task.id), + task_name=ready_or_waiting_task.task_spec.name, + task_title=ready_or_waiting_task.task_spec.description, + task_type=ready_or_waiting_task.task_spec.__class__.__name__, + task_status=ready_or_waiting_task.state.name, + task_data=json.dumps(ready_or_waiting_task.data), ) db.session.add(active_task) diff --git a/src/spiffworkflow_backend/services/process_instance_service.py b/src/spiffworkflow_backend/services/process_instance_service.py index cea76786..2e5fec8f 100644 --- a/src/spiffworkflow_backend/services/process_instance_service.py +++ b/src/spiffworkflow_backend/services/process_instance_service.py @@ -431,13 +431,10 @@ class ProcessInstanceService: spiff_task.task_spec.description, task_type, spiff_task.get_state_name(), - lane, - None, - "", - {}, - mi_type, - info["mi_count"], - info["mi_index"], + lane=lane, + multi_instance_type=mi_type, + multi_instance_count= info["mi_count"], + multi_instance_index=info["mi_index"], process_name=spiff_task.task_spec._wf_spec.description, properties=props, ) From d355331cc2be6ccca33f455a369e9786bf3400ce Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 25 Jul 2022 14:34:18 -0400 Subject: [PATCH 12/20] added api endpoint to return all tasks for a given process instance and updated task_show to return non-active task as well --- src/spiffworkflow_backend/api.yml | 26 +++ .../models/active_task.py | 4 - src/spiffworkflow_backend/models/task.py | 6 +- .../routes/process_api_blueprint.py | 180 +++++++----------- 4 files changed, 102 insertions(+), 114 deletions(-) diff --git a/src/spiffworkflow_backend/api.yml b/src/spiffworkflow_backend/api.yml index 86bab573..ee247681 100755 --- a/src/spiffworkflow_backend/api.yml +++ b/src/spiffworkflow_backend/api.yml @@ -671,6 +671,26 @@ paths: type: array items: $ref: "#/components/schemas/Task" + /process-instance/{process_instance_id}/tasks: + parameters: + - name: process_instance_id + in: path + required: true + description: The unique id of an existing process instance. + schema: + type: integer + get: + operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_task_list + summary: returns the list of all user tasks associated with process instance + responses: + "200": + description: list of tasks + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/Task" /tasks/{process_instance_id}/{task_id}: parameters: - name: task_id @@ -679,6 +699,12 @@ paths: description: The unique id of an existing process group. schema: type: string + - name: process_instance_id + in: path + required: true + description: The unique id of an existing process instance. + schema: + type: integer - name: terminate_loop in: query required: false diff --git a/src/spiffworkflow_backend/models/active_task.py b/src/spiffworkflow_backend/models/active_task.py index 180b4358..d0176ef4 100644 --- a/src/spiffworkflow_backend/models/active_task.py +++ b/src/spiffworkflow_backend/models/active_task.py @@ -26,10 +26,6 @@ class ActiveTaskModel(SpiffworkflowBaseDBModel): ), ) - # form_json: str | None = "" - # bpmn_json: str = "" - # preceding_spiffworkflow_user_task_id: int | None = None - assigned_principal: RelationshipProperty[PrincipalModel] = relationship( PrincipalModel ) diff --git a/src/spiffworkflow_backend/models/task.py b/src/spiffworkflow_backend/models/task.py index d5f9201e..2e2f8eaa 100644 --- a/src/spiffworkflow_backend/models/task.py +++ b/src/spiffworkflow_backend/models/task.py @@ -156,6 +156,10 @@ class Task: @property def serialized(self) -> dict[str, Any]: """Return object data in serializeable format.""" + multi_instance_type = None + if self.multi_instance_type: + MultiInstanceType(self.multi_instance_type) + return { "id": self.id, "name": self.name, @@ -166,7 +170,7 @@ class Task: "form": self.form, "documentation": self.documentation, "data": self.data, - "multi_instance_type": self.multi_instance_type, + "multi_instance_type": multi_instance_type, "multi_instance_count": self.multi_instance_count, "multi_instance_index": self.multi_instance_index, "process_name": self.process_name, diff --git a/src/spiffworkflow_backend/routes/process_api_blueprint.py b/src/spiffworkflow_backend/routes/process_api_blueprint.py index 29ce0da7..d5c73af3 100644 --- a/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -17,6 +17,7 @@ from flask.wrappers import Response from flask_bpmn.api.api_error import ApiError from flask_bpmn.models.db import db from SpiffWorkflow import TaskState # type: ignore +from SpiffWorkflow import Task as SpiffTask # type: ignore from sqlalchemy import desc from spiffworkflow_backend.exceptions.process_entity_not_found_error import ( @@ -554,23 +555,57 @@ def task_list_my_tasks(page: int = 1, per_page: int = 100) -> flask.wrappers.Res return make_response(jsonify(response_json), 200) +def process_instance_task_list(process_instance_id: int) -> flask.wrappers.Response: + process_instance = find_process_instance_by_id_or_raise( + process_instance_id + ) + processor = ProcessInstanceProcessor(process_instance) + all_spiff_user_tasks = processor.get_all_user_tasks() + + tasks = [ProcessInstanceService.spiff_task_to_api_task(spiff_task) for spiff_task in all_spiff_user_tasks] + + return make_response(jsonify(tasks), 200) + + def task_show(process_instance_id: int, task_id: str) -> flask.wrappers.Response: """Task_list_my_tasks.""" principal = find_principal_or_raise() - active_task_assigned_to_me = find_active_task_by_id_or_raise( - process_instance_id, task_id, principal.id - ) - process_instance = find_process_instance_by_id_or_raise( - active_task_assigned_to_me.process_instance_id + process_instance_id ) process_model = get_process_model( process_instance.process_model_identifier, process_instance.process_group_identifier, ) - if active_task_assigned_to_me.form_file_name is None: + active_task_assigned_to_me = ActiveTaskModel.query.filter_by( + process_instance_id=process_instance_id, + task_id=task_id, + assigned_principal_id=principal.id, + ).first() + + form_schema_file_name = "" + form_ui_schema_file_name = "" + task = None + if active_task_assigned_to_me: + form_schema_file_name = active_task_assigned_to_me.form_file_name + form_ui_schema_file_name = active_task_assigned_to_me.ui_form_file_name + task = active_task_assigned_to_me.to_task() + else: + spiff_task = get_spiff_task_from_process_instance(task_id, process_instance) + extensions = spiff_task.task_spec.extensions + + if "properties" in extensions: + properties = extensions["properties"] + if "formJsonSchemaFilename" in properties: + form_schema_file_name = properties["formJsonSchemaFilename"] + if "formUiSchemaFilename" in properties: + form_ui_schema_file_name = properties["formUiSchemaFilename"] + task = ProcessInstanceService.spiff_task_to_api_task(spiff_task) + task.data = spiff_task.data + + if form_schema_file_name is None: raise ( ApiError( code="missing_form_file", @@ -580,19 +615,18 @@ def task_show(process_instance_id: int, task_id: str) -> flask.wrappers.Response ) form_contents = prepare_form_data( - active_task_assigned_to_me.form_file_name, - json.loads(active_task_assigned_to_me.task_data), + form_schema_file_name, + task.data, process_model, ) - task = active_task_assigned_to_me.to_task() if form_contents: task.form_schema = form_contents - if active_task_assigned_to_me.ui_form_file_name: + if form_ui_schema_file_name: ui_form_contents = prepare_form_data( - active_task_assigned_to_me.ui_form_file_name, - json.loads(active_task_assigned_to_me.task_data), + form_ui_schema_file_name, + task.data, process_model, ) if ui_form_contents: @@ -601,89 +635,6 @@ def task_show(process_instance_id: int, task_id: str) -> flask.wrappers.Response return make_response(jsonify(task), 200) -def task_show_completed_user_task( - process_instance_id: int, spiffworkflow_task_uuid: str -) -> flask.wrappers.Response: - """Task_show_completed_user_task.""" - process_instance = find_process_instance_by_id_or_raise(process_instance_id) - processor = ProcessInstanceProcessor(process_instance) - - if processor.completed_user_tasks() is None: - raise ( - ApiError( - code="no_completed_user_tasks", - message=f"This process instance does not have any completed user tasks: {process_instance_id}", - status_code=400, - ) - ) - - spiffworkflow_task = None - preceding_spiffworkflow_user_task_id = None - following_spiffworkflow_user_task_id = None - for index, completed_user_task in enumerate(processor.completed_user_tasks()): - if str(completed_user_task.id) == spiffworkflow_task_uuid: - spiffworkflow_task = completed_user_task - preceding_spiffworkflow_user_task_id = get_value_from_array_with_index( - processor.completed_user_tasks(), index + 1 - ) - following_spiffworkflow_user_task_id = get_value_from_array_with_index( - processor.completed_user_tasks(), index - 1 - ) - - if spiffworkflow_task is None: - raise ( - ApiError( - code="no_completed_user_task_with_id", - message=f"This process instance does not have a completed user task with given id: {spiffworkflow_task_uuid}", - status_code=400, - ) - ) - - process_model = get_process_model( - process_instance.process_model_identifier, - process_instance.process_group_identifier, - ) - - task = ProcessInstanceService.spiff_task_to_api_task( - spiffworkflow_task, add_docs_and_forms=True - ) - - form_contents = prepare_form_data( - task.properties["properties"]["formJsonSchemaFilename"], - spiffworkflow_task.data, - process_model, - ) - if form_contents is not None: - task.form_schema = form_contents - - task.data = spiffworkflow_task.data - - if preceding_spiffworkflow_user_task_id: - task.preceding_spiffworkflow_user_task_id = ( - preceding_spiffworkflow_user_task_id.id - ) - - if following_spiffworkflow_user_task_id: - task.following_spiffworkflow_user_task_id = ( - following_spiffworkflow_user_task_id.id - ) - - principal = find_principal_or_raise() - active_task = ( - ActiveTaskModel.query.filter_by( - assigned_principal_id=principal.id, process_instance_id=process_instance_id - ).order_by( - desc(ActiveTaskModel.id) # type: ignore - ) - ).first() - - task.current_active_task_id = active_task.id - - return Response( - json.dumps(TaskSchema().dump(task)), status=200, mimetype="application/json" - ) - - def task_submit( process_instance_id: int, task_id: str, @@ -701,19 +652,8 @@ def task_submit( ) processor = ProcessInstanceProcessor(process_instance) - task_uuid = uuid.UUID( - active_task_assigned_to_me.task_id - ) - spiff_task = processor.bpmn_process_instance.get_task(task_uuid) + spiff_task = get_spiff_task_from_process_instance(task_id, process_instance, processor=processor) - if spiff_task is None: - raise ( - ApiError( - code="empty_task", - message="Processor failed to obtain task.", - status_code=500, - ) - ) if spiff_task.state != TaskState.READY: raise ( ApiError( @@ -852,14 +792,36 @@ def get_value_from_array_with_index(array: list, index: int) -> Any: def prepare_form_data( - form_file: str, spiffworkflow_data_json: dict, process_model: ProcessModelInfo + form_file: str, task_data: dict | None, process_model: ProcessModelInfo ) -> str: """Prepare_form_data.""" + if task_data is None: + return "" + file_contents = SpecFileService.get_data(process_model, form_file).decode("utf-8") # trade out pieces like "{{variable_name}}" for the corresponding form data value - for key, value in spiffworkflow_data_json.items(): + for key, value in task_data.items(): if isinstance(value, str) or isinstance(value, int): file_contents = file_contents.replace("{{" + key + "}}", str(value)) return file_contents + + +def get_spiff_task_from_process_instance(task_id: str, process_instance: ProcessInstanceModel, processor: ProcessInstanceProcessor | None = None) -> SpiffTask: + if processor is None: + processor = ProcessInstanceProcessor(process_instance) + task_uuid = uuid.UUID( + task_id + ) + spiff_task = processor.bpmn_process_instance.get_task(task_uuid) + + if spiff_task is None: + raise ( + ApiError( + code="empty_task", + message="Processor failed to obtain task.", + status_code=500, + ) + ) + return spiff_task From ab2e73011b76df4988e3b8c52f95a9511d1dd70a Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 25 Jul 2022 14:41:25 -0400 Subject: [PATCH 13/20] precommit and mypy --- .../routes/process_api_blueprint.py | 32 +++++++++++-------- .../services/process_instance_service.py | 8 +++-- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/spiffworkflow_backend/routes/process_api_blueprint.py b/src/spiffworkflow_backend/routes/process_api_blueprint.py index d5c73af3..19521831 100644 --- a/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -16,8 +16,8 @@ from flask import request from flask.wrappers import Response from flask_bpmn.api.api_error import ApiError from flask_bpmn.models.db import db -from SpiffWorkflow import TaskState # type: ignore from SpiffWorkflow import Task as SpiffTask # type: ignore +from SpiffWorkflow import TaskState from sqlalchemy import desc from spiffworkflow_backend.exceptions.process_entity_not_found_error import ( @@ -36,7 +36,6 @@ from spiffworkflow_backend.models.process_instance_report import ( ) from spiffworkflow_backend.models.process_model import ProcessModelInfo from spiffworkflow_backend.models.process_model import ProcessModelInfoSchema -from spiffworkflow_backend.models.task import TaskSchema from spiffworkflow_backend.services.error_handling_service import ErrorHandlingService from spiffworkflow_backend.services.process_instance_processor import ( ProcessInstanceProcessor, @@ -556,13 +555,15 @@ def task_list_my_tasks(page: int = 1, per_page: int = 100) -> flask.wrappers.Res def process_instance_task_list(process_instance_id: int) -> flask.wrappers.Response: - process_instance = find_process_instance_by_id_or_raise( - process_instance_id - ) + """Process_instance_task_list.""" + process_instance = find_process_instance_by_id_or_raise(process_instance_id) processor = ProcessInstanceProcessor(process_instance) all_spiff_user_tasks = processor.get_all_user_tasks() - tasks = [ProcessInstanceService.spiff_task_to_api_task(spiff_task) for spiff_task in all_spiff_user_tasks] + tasks = [ + ProcessInstanceService.spiff_task_to_api_task(spiff_task) + for spiff_task in all_spiff_user_tasks + ] return make_response(jsonify(tasks), 200) @@ -571,9 +572,7 @@ def task_show(process_instance_id: int, task_id: str) -> flask.wrappers.Response """Task_list_my_tasks.""" principal = find_principal_or_raise() - process_instance = find_process_instance_by_id_or_raise( - process_instance_id - ) + process_instance = find_process_instance_by_id_or_raise(process_instance_id) process_model = get_process_model( process_instance.process_model_identifier, process_instance.process_group_identifier, @@ -652,7 +651,9 @@ def task_submit( ) processor = ProcessInstanceProcessor(process_instance) - spiff_task = get_spiff_task_from_process_instance(task_id, process_instance, processor=processor) + spiff_task = get_spiff_task_from_process_instance( + task_id, process_instance, processor=processor + ) if spiff_task.state != TaskState.READY: raise ( @@ -808,12 +809,15 @@ def prepare_form_data( return file_contents -def get_spiff_task_from_process_instance(task_id: str, process_instance: ProcessInstanceModel, processor: ProcessInstanceProcessor | None = None) -> SpiffTask: +def get_spiff_task_from_process_instance( + task_id: str, + process_instance: ProcessInstanceModel, + processor: ProcessInstanceProcessor | None = None, +) -> SpiffTask: + """Get_spiff_task_from_process_instance.""" if processor is None: processor = ProcessInstanceProcessor(process_instance) - task_uuid = uuid.UUID( - task_id - ) + task_uuid = uuid.UUID(task_id) spiff_task = processor.bpmn_process_instance.get_task(task_uuid) if spiff_task is None: diff --git a/src/spiffworkflow_backend/services/process_instance_service.py b/src/spiffworkflow_backend/services/process_instance_service.py index 2e5fec8f..822c825f 100644 --- a/src/spiffworkflow_backend/services/process_instance_service.py +++ b/src/spiffworkflow_backend/services/process_instance_service.py @@ -304,6 +304,10 @@ class ProcessInstanceService: form_data = ProcessInstanceService.extract_form_data( spiff_task.data, spiff_task ) + multi_instance_type_value = "" + if task.multi_instance_type: + multi_instance_type_value = task.multi_instance_type.value + task_event = TaskEventModel( # study_id=processor.workflow_model.study_id, user_id=user_id, @@ -317,7 +321,7 @@ class ProcessInstanceService: task_state=task.state, task_lane=task.lane, form_data=form_data, - mi_type=task.multi_instance_type.value, # Some tasks have a repeat behavior. + mi_type=multi_instance_type_value, # Some tasks have a repeat behavior. mi_count=task.multi_instance_count, # This is the number of times the task could repeat. mi_index=task.multi_instance_index, # And the index of the currently repeating task. process_name=task.process_name, @@ -433,7 +437,7 @@ class ProcessInstanceService: spiff_task.get_state_name(), lane=lane, multi_instance_type=mi_type, - multi_instance_count= info["mi_count"], + multi_instance_count=info["mi_count"], multi_instance_index=info["mi_index"], process_name=spiff_task.task_spec._wf_spec.description, properties=props, From f6ba35c02e5e07ed60a3b9513e2d22d411af56cb Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 25 Jul 2022 14:58:06 -0400 Subject: [PATCH 14/20] fixed mypy issue --- src/spiffworkflow_backend/models/task.py | 9 --------- src/spiffworkflow_backend/scripts/script.py | 4 ++++ 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/spiffworkflow_backend/models/task.py b/src/spiffworkflow_backend/models/task.py index 2e2f8eaa..c626a61d 100644 --- a/src/spiffworkflow_backend/models/task.py +++ b/src/spiffworkflow_backend/models/task.py @@ -113,9 +113,6 @@ class Task: process_instance_id: int | None = None, form_schema: str | None = None, form_ui_schema: str | None = None, - # preceding_spiffworkflow_user_task_id: Union[str, int, None] = None, - # following_spiffworkflow_user_task_id: Union[str, int, None] = None, - # current_active_task_id: Union[int, None] = None, ): """__init__.""" self.id = id @@ -134,9 +131,6 @@ class Task: self.process_instance_id = process_instance_id self.form_schema = form_schema self.form_ui_schema = form_ui_schema - # self.preceding_spiffworkflow_user_task_id = preceding_spiffworkflow_user_task_id - # self.following_spiffworkflow_user_task_id = following_spiffworkflow_user_task_id - # self.current_active_task_id = current_active_task_id self.multi_instance_type = ( multi_instance_type # Some tasks have a repeat behavior. @@ -278,9 +272,6 @@ class TaskSchema(Schema): "process_instance_id", "form_schema", "form_ui_schema", - # "preceding_spiffworkflow_user_task_id", - # "following_spiffworkflow_user_task_id", - # "current_active_task_id", ] multi_instance_type = EnumField(MultiInstanceType) diff --git a/src/spiffworkflow_backend/scripts/script.py b/src/spiffworkflow_backend/scripts/script.py index 1724eb5c..d7a2c67a 100644 --- a/src/spiffworkflow_backend/scripts/script.py +++ b/src/spiffworkflow_backend/scripts/script.py @@ -150,6 +150,10 @@ class Script: def add_data_to_task(self, task: Task, data: Any) -> None: """Add_data_to_task.""" key = self.__class__.__name__ + + if task.data is None: + task.data = {} + if key in task.data: task.data[key].update(data) else: From e34d1f83a2e4f617d39407d9bf5b4ea22c7fb676 Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 25 Jul 2022 15:07:32 -0400 Subject: [PATCH 15/20] some more mypy issues --- src/spiffworkflow_backend/models/task.py | 14 +++++++------- .../routes/process_api_blueprint.py | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/spiffworkflow_backend/models/task.py b/src/spiffworkflow_backend/models/task.py index c626a61d..2035312c 100644 --- a/src/spiffworkflow_backend/models/task.py +++ b/src/spiffworkflow_backend/models/task.py @@ -1,6 +1,6 @@ """Task.""" import enum -from typing import Any +from typing import Any, Union import marshmallow from marshmallow import Schema @@ -101,18 +101,18 @@ class Task: title: str, type: str, state: str, - lane: str | None = None, + lane: Union[str, None] = None, form: None = None, documentation: str = "", data: dict[str, Any] | None = None, - multi_instance_type: MultiInstanceType | None = None, + multi_instance_type: Union[MultiInstanceType, None] = None, multi_instance_count: str = "", multi_instance_index: str = "", process_name: str = "", - properties: dict | None = None, - process_instance_id: int | None = None, - form_schema: str | None = None, - form_ui_schema: str | None = None, + properties: Union[dict, None] = None, + process_instance_id: Union[int, None] = None, + form_schema: Union[str, None] = None, + form_ui_schema: Union[str, None] = None, ): """__init__.""" self.id = id diff --git a/src/spiffworkflow_backend/routes/process_api_blueprint.py b/src/spiffworkflow_backend/routes/process_api_blueprint.py index 19521831..df390a72 100644 --- a/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -793,7 +793,7 @@ def get_value_from_array_with_index(array: list, index: int) -> Any: def prepare_form_data( - form_file: str, task_data: dict | None, process_model: ProcessModelInfo + form_file: str, task_data: Union[dict, None], process_model: ProcessModelInfo ) -> str: """Prepare_form_data.""" if task_data is None: @@ -812,7 +812,7 @@ def prepare_form_data( def get_spiff_task_from_process_instance( task_id: str, process_instance: ProcessInstanceModel, - processor: ProcessInstanceProcessor | None = None, + processor: Union[ProcessInstanceProcessor, None] = None, ) -> SpiffTask: """Get_spiff_task_from_process_instance.""" if processor is None: From 71f18c8306d81396d84ecf0adbd3059d1448b5ac Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 25 Jul 2022 15:17:04 -0400 Subject: [PATCH 16/20] more precommit and mypy --- src/spiffworkflow_backend/models/task.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/spiffworkflow_backend/models/task.py b/src/spiffworkflow_backend/models/task.py index 2035312c..1384f8f5 100644 --- a/src/spiffworkflow_backend/models/task.py +++ b/src/spiffworkflow_backend/models/task.py @@ -1,6 +1,7 @@ """Task.""" import enum -from typing import Any, Union +from typing import Any +from typing import Union import marshmallow from marshmallow import Schema @@ -104,7 +105,7 @@ class Task: lane: Union[str, None] = None, form: None = None, documentation: str = "", - data: dict[str, Any] | None = None, + data: Union[dict[str, Any], None] = None, multi_instance_type: Union[MultiInstanceType, None] = None, multi_instance_count: str = "", multi_instance_index: str = "", From 772e5352ff14daf39cfa1e4fdbdf727e26ed7dd4 Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 25 Jul 2022 16:46:10 -0400 Subject: [PATCH 17/20] added all_tasks option to process-instance/tasks endpoint and cleaned process instance show endpoint --- src/spiffworkflow_backend/api.yml | 6 +++ .../models/process_instance.py | 9 ----- .../routes/process_api_blueprint.py | 37 +++++++------------ 3 files changed, 19 insertions(+), 33 deletions(-) diff --git a/src/spiffworkflow_backend/api.yml b/src/spiffworkflow_backend/api.yml index ee247681..be213041 100755 --- a/src/spiffworkflow_backend/api.yml +++ b/src/spiffworkflow_backend/api.yml @@ -679,6 +679,12 @@ paths: description: The unique id of an existing process instance. schema: type: integer + - name: all_tasks + in: query + required: false + description: If true, this wil return all tasks associated with the process instance and not just user tasks. + schema: + type: boolean get: operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_task_list summary: returns the list of all user tasks associated with process instance diff --git a/src/spiffworkflow_backend/models/process_instance.py b/src/spiffworkflow_backend/models/process_instance.py index 9b135a8f..439e7701 100644 --- a/src/spiffworkflow_backend/models/process_instance.py +++ b/src/spiffworkflow_backend/models/process_instance.py @@ -99,10 +99,7 @@ class ProcessInstanceModel(SpiffworkflowBaseDBModel): created_at_in_seconds: int = db.Column(db.Integer) status: str = db.Column(db.String(50)) - data: dict | None = None - bpmn_xml_file_name: str | None = None bpmn_xml_file_contents: bytes | None = None - spiffworkflow_active_task_id: str | None = None @property def serialized(self) -> dict[str, Any]: @@ -116,14 +113,10 @@ class ProcessInstanceModel(SpiffworkflowBaseDBModel): "process_model_identifier": self.process_model_identifier, "process_group_identifier": self.process_group_identifier, "status": self.status, - "bpmn_json": self.bpmn_json, "start_in_seconds": self.start_in_seconds, "end_in_seconds": self.end_in_seconds, "process_initiator_id": self.process_initiator_id, - "data": self.data, - "bpmn_xml_file_name": self.bpmn_xml_file_name, "bpmn_xml_file_contents": local_bpmn_xml_file_contents, - "spiffworkflow_active_task_id": self.spiffworkflow_active_task_id, } @property @@ -149,8 +142,6 @@ class ProcessInstanceModelSchema(Schema): "process_model_identifier", "process_group_identifier", "process_initiator_id", - # "process_initiator", - "bpmn_json", "start_in_seconds", "end_in_seconds", "updated_at_in_seconds", diff --git a/src/spiffworkflow_backend/routes/process_api_blueprint.py b/src/spiffworkflow_backend/routes/process_api_blueprint.py index c203623a..e64c8b85 100644 --- a/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -388,35 +388,18 @@ def process_instance_list( def process_instance_show( - process_group_id: str, process_model_id: str, process_instance_id: int + process_group_id: str, process_model_id: str, process_instance_id: int ) -> flask.wrappers.Response: """Create_process_instance.""" process_instance = find_process_instance_by_id_or_raise(process_instance_id) process_model = get_process_model(process_model_id, process_group_id) - processor = ProcessInstanceProcessor(process_instance) - process_instance.data = processor.get_data() - if process_model.primary_file_name: bpmn_xml_file_contents = SpecFileService.get_data( process_model, process_model.primary_file_name ) - process_instance.bpmn_xml_file_name = process_model.primary_file_name process_instance.bpmn_xml_file_contents = bpmn_xml_file_contents - active_task = ( - ActiveTaskModel.query.filter_by( - process_instance_id=process_instance_id - ).order_by( - desc(ActiveTaskModel.id) # type: ignore - ) - ).first() - - if active_task: - process_instance.spiffworkflow_active_task_id = ( - active_task.spiffworkflow_task_id - ) - return make_response(jsonify(process_instance), 200) @@ -576,16 +559,22 @@ def task_list_my_tasks(page: int = 1, per_page: int = 100) -> flask.wrappers.Res return make_response(jsonify(response_json), 200) -def process_instance_task_list(process_instance_id: int) -> flask.wrappers.Response: +def process_instance_task_list(process_instance_id: int, all_tasks: bool = False) -> flask.wrappers.Response: """Process_instance_task_list.""" process_instance = find_process_instance_by_id_or_raise(process_instance_id) processor = ProcessInstanceProcessor(process_instance) - all_spiff_user_tasks = processor.get_all_user_tasks() - tasks = [ - ProcessInstanceService.spiff_task_to_api_task(spiff_task) - for spiff_task in all_spiff_user_tasks - ] + spiff_tasks = None + if all_tasks: + spiff_tasks = processor.bpmn_process_instance.get_tasks(TaskState.ANY_MASK) + else: + spiff_tasks = processor.get_all_user_tasks() + + tasks = [] + for spiff_task in spiff_tasks: + task = ProcessInstanceService.spiff_task_to_api_task(spiff_task) + task.data = spiff_task.data + tasks.append(task) return make_response(jsonify(tasks), 200) From 2c5141ce3680ec6ed2b01074e464c2d2b35b04c2 Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 25 Jul 2022 16:47:43 -0400 Subject: [PATCH 18/20] precommit --- src/spiffworkflow_backend/routes/process_api_blueprint.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/spiffworkflow_backend/routes/process_api_blueprint.py b/src/spiffworkflow_backend/routes/process_api_blueprint.py index e64c8b85..c1711fc8 100644 --- a/src/spiffworkflow_backend/routes/process_api_blueprint.py +++ b/src/spiffworkflow_backend/routes/process_api_blueprint.py @@ -388,7 +388,7 @@ def process_instance_list( def process_instance_show( - process_group_id: str, process_model_id: str, process_instance_id: int + process_group_id: str, process_model_id: str, process_instance_id: int ) -> flask.wrappers.Response: """Create_process_instance.""" process_instance = find_process_instance_by_id_or_raise(process_instance_id) @@ -559,7 +559,9 @@ def task_list_my_tasks(page: int = 1, per_page: int = 100) -> flask.wrappers.Res return make_response(jsonify(response_json), 200) -def process_instance_task_list(process_instance_id: int, all_tasks: bool = False) -> flask.wrappers.Response: +def process_instance_task_list( + process_instance_id: int, all_tasks: bool = False +) -> flask.wrappers.Response: """Process_instance_task_list.""" process_instance = find_process_instance_by_id_or_raise(process_instance_id) processor = ProcessInstanceProcessor(process_instance) From caa570cbcdbc490ec0d783a154b05c6155500450 Mon Sep 17 00:00:00 2001 From: jasquat Date: Mon, 25 Jul 2022 17:12:12 -0400 Subject: [PATCH 19/20] put bpmn_json back into serialized process instance since tests are using it --- src/spiffworkflow_backend/models/process_instance.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/spiffworkflow_backend/models/process_instance.py b/src/spiffworkflow_backend/models/process_instance.py index 439e7701..3f511723 100644 --- a/src/spiffworkflow_backend/models/process_instance.py +++ b/src/spiffworkflow_backend/models/process_instance.py @@ -113,6 +113,7 @@ class ProcessInstanceModel(SpiffworkflowBaseDBModel): "process_model_identifier": self.process_model_identifier, "process_group_identifier": self.process_group_identifier, "status": self.status, + "bpmn_json": self.bpmn_json, "start_in_seconds": self.start_in_seconds, "end_in_seconds": self.end_in_seconds, "process_initiator_id": self.process_initiator_id, From cfa81026709aa9cfaa4417bf3baaf3e78e51cf4d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Jul 2022 20:54:53 +0000 Subject: [PATCH 20/20] Bump virtualenv from 20.15.1 to 20.16.0 in /.github/workflows Bumps [virtualenv](https://github.com/pypa/virtualenv) from 20.15.1 to 20.16.0. - [Release notes](https://github.com/pypa/virtualenv/releases) - [Changelog](https://github.com/pypa/virtualenv/blob/main/docs/changelog.rst) - [Commits](https://github.com/pypa/virtualenv/compare/20.15.1...20.16.0) --- updated-dependencies: - dependency-name: virtualenv dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/constraints.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/constraints.txt b/.github/workflows/constraints.txt index 90aa9d15..dc29c1ad 100644 --- a/.github/workflows/constraints.txt +++ b/.github/workflows/constraints.txt @@ -2,4 +2,4 @@ pip==22.2 nox==2022.1.7 nox-poetry==1.0.1 poetry==1.1.14 -virtualenv==20.15.1 +virtualenv==20.16.0