moved process groups, models, and instances api methods to own controller files w/ burnettk
This commit is contained in:
parent
acc57410d9
commit
05417039fe
|
@ -23,7 +23,6 @@ from spiffworkflow_backend.routes.admin_blueprint.admin_blueprint import admin_b
|
|||
from spiffworkflow_backend.routes.openid_blueprint.openid_blueprint import (
|
||||
openid_blueprint,
|
||||
)
|
||||
from spiffworkflow_backend.routes.process_api_blueprint import process_api_blueprint
|
||||
from spiffworkflow_backend.routes.user import verify_token
|
||||
from spiffworkflow_backend.routes.user_blueprint import user_blueprint
|
||||
from spiffworkflow_backend.services.authorization_service import AuthorizationService
|
||||
|
@ -104,7 +103,6 @@ def create_app() -> flask.app.Flask:
|
|||
migrate.init_app(app, db)
|
||||
|
||||
app.register_blueprint(user_blueprint)
|
||||
app.register_blueprint(process_api_blueprint)
|
||||
app.register_blueprint(api_error_blueprint)
|
||||
app.register_blueprint(admin_blueprint, url_prefix="/admin")
|
||||
app.register_blueprint(openid_blueprint, url_prefix="/openid")
|
||||
|
|
|
@ -8,10 +8,6 @@ servers:
|
|||
- url: http://localhost:5000/v1.0
|
||||
# this is handled in flask now
|
||||
security: []
|
||||
# - jwt: ["secret"]
|
||||
# - oAuth2AuthCode:
|
||||
# - read_email
|
||||
# - uid
|
||||
|
||||
paths:
|
||||
/login:
|
||||
|
@ -22,7 +18,6 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
get:
|
||||
security: []
|
||||
summary: redirect to open id authentication server
|
||||
operationId: spiffworkflow_backend.routes.user.login
|
||||
tags:
|
||||
|
@ -48,7 +43,6 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
get:
|
||||
security: []
|
||||
operationId: spiffworkflow_backend.routes.user.login_return
|
||||
tags:
|
||||
- Authentication
|
||||
|
@ -68,7 +62,6 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
get:
|
||||
security: []
|
||||
operationId: spiffworkflow_backend.routes.user.logout
|
||||
summary: Logout authenticated user
|
||||
tags:
|
||||
|
@ -78,7 +71,6 @@ paths:
|
|||
description: Logout Authenticated User
|
||||
/logout_return:
|
||||
get:
|
||||
security: []
|
||||
operationId: spiffworkflow_backend.routes.user.logout_return
|
||||
summary: Logout authenticated user
|
||||
tags:
|
||||
|
@ -89,7 +81,6 @@ paths:
|
|||
|
||||
/login_api:
|
||||
get:
|
||||
security: []
|
||||
operationId: spiffworkflow_backend.routes.user.login_api
|
||||
summary: Authenticate user for API access
|
||||
tags:
|
||||
|
@ -115,7 +106,6 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
get:
|
||||
security: []
|
||||
operationId: spiffworkflow_backend.routes.user.login_api_return
|
||||
tags:
|
||||
- Authentication
|
||||
|
@ -125,7 +115,6 @@ paths:
|
|||
|
||||
/status:
|
||||
get:
|
||||
security: []
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.status
|
||||
summary: Returns 200 if the server is Responding
|
||||
tags:
|
||||
|
@ -160,7 +149,7 @@ paths:
|
|||
schema:
|
||||
type: integer
|
||||
get:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_group_list
|
||||
operationId: spiffworkflow_backend.routes.process_groups_controller.process_group_list
|
||||
summary: get list
|
||||
tags:
|
||||
- Process Groups
|
||||
|
@ -174,7 +163,7 @@ paths:
|
|||
items:
|
||||
$ref: "#/components/schemas/ProcessModelCategory"
|
||||
post:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_group_create
|
||||
operationId: spiffworkflow_backend.routes.process_groups_controller.process_group_create
|
||||
summary: Add process group
|
||||
tags:
|
||||
- Process Groups
|
||||
|
@ -201,7 +190,7 @@ paths:
|
|||
type: string
|
||||
# process_group_show
|
||||
get:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_group_show
|
||||
operationId: spiffworkflow_backend.routes.process_groups_controller.process_group_show
|
||||
summary: Returns a single process group
|
||||
tags:
|
||||
- Process Groups
|
||||
|
@ -213,7 +202,7 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/ProcessModelCategory"
|
||||
delete:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_group_delete
|
||||
operationId: spiffworkflow_backend.routes.process_groups_controller.process_group_delete
|
||||
summary: Deletes a single process group
|
||||
tags:
|
||||
- Process Groups
|
||||
|
@ -221,7 +210,7 @@ paths:
|
|||
"200":
|
||||
description: The process group was deleted.
|
||||
put:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_group_update
|
||||
operationId: spiffworkflow_backend.routes.process_groups_controller.process_group_update
|
||||
summary: Updates a single process group
|
||||
tags:
|
||||
- Process Groups
|
||||
|
@ -253,7 +242,7 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
put:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_group_move
|
||||
operationId: spiffworkflow_backend.routes.process_groups_controller.process_group_move
|
||||
summary: returns the new group
|
||||
tags:
|
||||
- Process Groups
|
||||
|
@ -298,7 +287,7 @@ paths:
|
|||
schema:
|
||||
type: integer
|
||||
get:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_model_list
|
||||
operationId: spiffworkflow_backend.routes.process_models_controller.process_model_list
|
||||
summary: Return a list of process models for a given process group
|
||||
tags:
|
||||
- Process Models
|
||||
|
@ -321,7 +310,7 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
post:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_model_create
|
||||
operationId: spiffworkflow_backend.routes.process_models_controller.process_model_create
|
||||
summary: Creates a new process model with the given parameters.
|
||||
tags:
|
||||
- Process Models
|
||||
|
@ -347,7 +336,7 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
post:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.add_file
|
||||
operationId: spiffworkflow_backend.routes.process_models_controller.process_model_file_create
|
||||
summary: Add a new workflow spec file
|
||||
tags:
|
||||
- Process Model Files
|
||||
|
@ -377,7 +366,7 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
get:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_model_show
|
||||
operationId: spiffworkflow_backend.routes.process_models_controller.process_model_show
|
||||
summary: Returns a single process model
|
||||
tags:
|
||||
- Process Models
|
||||
|
@ -389,7 +378,7 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/ProcessModel"
|
||||
put:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_model_update
|
||||
operationId: spiffworkflow_backend.routes.process_models_controller.process_model_update
|
||||
summary: Modifies an existing process model with the given parameters.
|
||||
tags:
|
||||
- Process Models
|
||||
|
@ -406,7 +395,7 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/ProcessModel"
|
||||
delete:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_model_delete
|
||||
operationId: spiffworkflow_backend.routes.process_models_controller.process_model_delete
|
||||
summary: Removes an existing process model
|
||||
tags:
|
||||
- Process Models
|
||||
|
@ -433,7 +422,7 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
put:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_model_move
|
||||
operationId: spiffworkflow_backend.routes.process_models_controller.process_model_move
|
||||
summary: returns the new model
|
||||
tags:
|
||||
- Process Models
|
||||
|
@ -460,7 +449,7 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
post:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_model_publish
|
||||
operationId: spiffworkflow_backend.routes.process_models_controller.process_model_publish
|
||||
summary: Merge changes from this model to another branch.
|
||||
tags:
|
||||
- Process Models
|
||||
|
@ -608,7 +597,7 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
get:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_list_for_me
|
||||
operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_list_for_me
|
||||
summary: Returns a list of process instances that are associated with me.
|
||||
tags:
|
||||
- Process Instances
|
||||
|
@ -721,7 +710,7 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
get:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_list
|
||||
operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_list
|
||||
summary: Returns a list of process instances.
|
||||
tags:
|
||||
- Process Instances
|
||||
|
@ -786,7 +775,7 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
post:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_create
|
||||
operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_create
|
||||
summary: Creates an process instance from a process model and returns the instance
|
||||
tags:
|
||||
- Process Instances
|
||||
|
@ -833,7 +822,7 @@ paths:
|
|||
get:
|
||||
tags:
|
||||
- Process Instances
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_task_list_without_task_data_for_me
|
||||
operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_task_list_without_task_data_for_me
|
||||
summary: returns the list of all user tasks associated with process instance without the task data
|
||||
responses:
|
||||
"200":
|
||||
|
@ -880,7 +869,7 @@ paths:
|
|||
get:
|
||||
tags:
|
||||
- Process Instances
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_task_list_without_task_data
|
||||
operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_task_list_without_task_data
|
||||
summary: returns the list of all user tasks associated with process instance without the task data
|
||||
responses:
|
||||
"200":
|
||||
|
@ -915,7 +904,7 @@ paths:
|
|||
get:
|
||||
tags:
|
||||
- Process Instances
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_show_for_me
|
||||
operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_show_for_me
|
||||
summary: Show information about a process instance that is associated with me
|
||||
responses:
|
||||
"200":
|
||||
|
@ -948,7 +937,7 @@ paths:
|
|||
get:
|
||||
tags:
|
||||
- Process Instances
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_show
|
||||
operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_show
|
||||
summary: Show information about a process instance
|
||||
responses:
|
||||
"200":
|
||||
|
@ -958,7 +947,7 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/Workflow"
|
||||
delete:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_delete
|
||||
operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_delete
|
||||
summary: Deletes a single process instance
|
||||
tags:
|
||||
- Process Instances
|
||||
|
@ -985,7 +974,7 @@ paths:
|
|||
schema:
|
||||
type: boolean
|
||||
post:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_run
|
||||
operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_run
|
||||
summary: Run a process instance
|
||||
tags:
|
||||
- Process Instances
|
||||
|
@ -1006,7 +995,7 @@ paths:
|
|||
schema:
|
||||
type: integer
|
||||
post:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_terminate
|
||||
operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_terminate
|
||||
summary: Terminate a process instance
|
||||
tags:
|
||||
- Process Instances
|
||||
|
@ -1027,7 +1016,7 @@ paths:
|
|||
schema:
|
||||
type: integer
|
||||
post:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_suspend
|
||||
operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_suspend
|
||||
summary: Suspend a process instance
|
||||
tags:
|
||||
- Process Instances
|
||||
|
@ -1048,7 +1037,7 @@ paths:
|
|||
schema:
|
||||
type: integer
|
||||
post:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_resume
|
||||
operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_resume
|
||||
summary: Resume a process instance
|
||||
tags:
|
||||
- Process Instances
|
||||
|
@ -1075,7 +1064,7 @@ paths:
|
|||
schema:
|
||||
type: integer
|
||||
get:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_report_list
|
||||
operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_report_list
|
||||
summary: Returns all process instance reports for process model
|
||||
tags:
|
||||
- Process Instances
|
||||
|
@ -1089,7 +1078,7 @@ paths:
|
|||
items:
|
||||
$ref: "#/components/schemas/Workflow"
|
||||
post:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_report_create
|
||||
operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_report_create
|
||||
summary: Returns all process instance reports for process model
|
||||
tags:
|
||||
- Process Instances
|
||||
|
@ -1103,7 +1092,7 @@ paths:
|
|||
|
||||
/process-instances/reports/columns:
|
||||
get:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_report_column_list
|
||||
operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_report_column_list
|
||||
summary: Returns all available columns for a process instance report.
|
||||
tags:
|
||||
- Process Instances
|
||||
|
@ -1138,7 +1127,7 @@ paths:
|
|||
schema:
|
||||
type: integer
|
||||
get:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_report_show
|
||||
operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_report_show
|
||||
summary: Returns a report of process instances for a given process model
|
||||
tags:
|
||||
- Process Instances
|
||||
|
@ -1152,7 +1141,7 @@ paths:
|
|||
items:
|
||||
$ref: "#/components/schemas/Workflow"
|
||||
put:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_report_update
|
||||
operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_report_update
|
||||
summary: Updates a process instance report
|
||||
tags:
|
||||
- Process Instances
|
||||
|
@ -1164,7 +1153,7 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/OkTrue"
|
||||
delete:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_report_delete
|
||||
operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_report_delete
|
||||
summary: Delete a process instance report
|
||||
tags:
|
||||
- Process Instances
|
||||
|
@ -1191,7 +1180,7 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
get:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.get_file
|
||||
operationId: spiffworkflow_backend.routes.process_models_controller.process_model_file_show
|
||||
summary: Returns metadata about the file
|
||||
tags:
|
||||
- Process Model Files
|
||||
|
@ -1203,7 +1192,7 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/File"
|
||||
put:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_model_file_update
|
||||
operationId: spiffworkflow_backend.routes.process_models_controller.process_model_file_update
|
||||
summary: save the contents to the given file
|
||||
tags:
|
||||
- Process Model Files
|
||||
|
@ -1226,7 +1215,7 @@ paths:
|
|||
schema:
|
||||
$ref: "#/components/schemas/OkTrue"
|
||||
delete:
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_model_file_delete
|
||||
operationId: spiffworkflow_backend.routes.process_models_controller.process_model_file_delete
|
||||
summary: Removes an existing process model file
|
||||
tags:
|
||||
- Process Model Files
|
||||
|
@ -1255,7 +1244,6 @@ paths:
|
|||
get:
|
||||
tags:
|
||||
- Tasks
|
||||
# security: []
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.task_list_my_tasks
|
||||
summary: returns the list of ready or waiting tasks for a user
|
||||
responses:
|
||||
|
@ -1406,7 +1394,7 @@ paths:
|
|||
get:
|
||||
tags:
|
||||
- Process Instances
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_task_list_with_task_data
|
||||
operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_task_list_with_task_data
|
||||
summary: returns the list of all user tasks associated with process instance with the task data
|
||||
responses:
|
||||
"200":
|
||||
|
@ -1539,8 +1527,6 @@ paths:
|
|||
schema:
|
||||
type: string
|
||||
get:
|
||||
# disable security so we can get the token from query params instead
|
||||
security: []
|
||||
tags:
|
||||
- Authentications
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.authentication_callback
|
||||
|
@ -1697,7 +1683,7 @@ paths:
|
|||
get:
|
||||
tags:
|
||||
- Process Instances
|
||||
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_instance_log_list
|
||||
operationId: spiffworkflow_backend.routes.process_instances_controller.process_instance_log_list
|
||||
summary: returns a list of logs associated with the process instance
|
||||
responses:
|
||||
"200":
|
||||
|
@ -1843,16 +1829,6 @@ components:
|
|||
scopes:
|
||||
read_email: read email
|
||||
x-tokenInfoFunc: spiffworkflow_backend.routes.user.get_scope
|
||||
# oAuth2AuthCode:
|
||||
# type: oauth2
|
||||
# description: authenticate with openid server
|
||||
# flows:
|
||||
# implicit:
|
||||
# authorizationUrl: /v1.0/login_api
|
||||
# scopes:
|
||||
# uid: uid
|
||||
# x-tokenInfoUrl: localhost:7000/v1.0/login_api_return
|
||||
# x-tokenInfoFunc: spiffworkflow_backend.routes.user.get_scope
|
||||
|
||||
schemas:
|
||||
OkTrue:
|
||||
|
|
|
@ -158,290 +158,6 @@ def permissions_check(body: Dict[str, Dict[str, list[str]]]) -> flask.wrappers.R
|
|||
return make_response(jsonify({"results": response_dict}), 200)
|
||||
|
||||
|
||||
def un_modify_modified_process_model_id(modified_process_model_identifier: str) -> str:
|
||||
"""Un_modify_modified_process_model_id."""
|
||||
return modified_process_model_identifier.replace(":", "/")
|
||||
|
||||
|
||||
def process_group_create(body: dict) -> flask.wrappers.Response:
|
||||
"""Add_process_group."""
|
||||
process_group = ProcessGroup(**body)
|
||||
ProcessModelService.add_process_group(process_group)
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} added process group {process_group.id}"
|
||||
)
|
||||
return make_response(jsonify(process_group), 201)
|
||||
|
||||
|
||||
def process_group_delete(modified_process_group_id: str) -> flask.wrappers.Response:
|
||||
"""Process_group_delete."""
|
||||
process_group_id = un_modify_modified_process_model_id(modified_process_group_id)
|
||||
ProcessModelService().process_group_delete(process_group_id)
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} deleted process group {process_group_id}"
|
||||
)
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_group_update(
|
||||
modified_process_group_id: str, body: dict
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process Group Update."""
|
||||
body_include_list = ["display_name", "description"]
|
||||
body_filtered = {
|
||||
include_item: body[include_item]
|
||||
for include_item in body_include_list
|
||||
if include_item in body
|
||||
}
|
||||
|
||||
process_group_id = un_modify_modified_process_model_id(modified_process_group_id)
|
||||
process_group = ProcessGroup(id=process_group_id, **body_filtered)
|
||||
ProcessModelService.update_process_group(process_group)
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} updated process group {process_group_id}"
|
||||
)
|
||||
return make_response(jsonify(process_group), 200)
|
||||
|
||||
|
||||
def process_group_list(
|
||||
process_group_identifier: Optional[str] = None, page: int = 1, per_page: int = 100
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_group_list."""
|
||||
if process_group_identifier is not None:
|
||||
process_groups = ProcessModelService.get_process_groups(
|
||||
process_group_identifier
|
||||
)
|
||||
else:
|
||||
process_groups = ProcessModelService.get_process_groups()
|
||||
batch = ProcessModelService().get_batch(
|
||||
items=process_groups, page=page, per_page=per_page
|
||||
)
|
||||
pages = len(process_groups) // per_page
|
||||
remainder = len(process_groups) % per_page
|
||||
if remainder > 0:
|
||||
pages += 1
|
||||
|
||||
response_json = {
|
||||
"results": ProcessGroupSchema(many=True).dump(batch),
|
||||
"pagination": {
|
||||
"count": len(batch),
|
||||
"total": len(process_groups),
|
||||
"pages": pages,
|
||||
},
|
||||
}
|
||||
return Response(json.dumps(response_json), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_group_show(
|
||||
modified_process_group_id: str,
|
||||
) -> Any:
|
||||
"""Process_group_show."""
|
||||
process_group_id = un_modify_modified_process_model_id(modified_process_group_id)
|
||||
try:
|
||||
process_group = ProcessModelService.get_process_group(process_group_id)
|
||||
except ProcessEntityNotFoundError as exception:
|
||||
raise (
|
||||
ApiError(
|
||||
error_code="process_group_cannot_be_found",
|
||||
message=f"Process group cannot be found: {process_group_id}",
|
||||
status_code=400,
|
||||
)
|
||||
) from exception
|
||||
|
||||
process_group.parent_groups = ProcessModelService.get_parent_group_array(
|
||||
process_group.id
|
||||
)
|
||||
return make_response(jsonify(process_group), 200)
|
||||
|
||||
|
||||
def process_group_move(
|
||||
modified_process_group_identifier: str, new_location: str
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_group_move."""
|
||||
original_process_group_id = un_modify_modified_process_model_id(
|
||||
modified_process_group_identifier
|
||||
)
|
||||
new_process_group = ProcessModelService().process_group_move(
|
||||
original_process_group_id, new_location
|
||||
)
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} moved process group {original_process_group_id} to {new_process_group.id}"
|
||||
)
|
||||
return make_response(jsonify(new_process_group), 200)
|
||||
|
||||
|
||||
def process_model_create(
|
||||
modified_process_group_id: str, body: Dict[str, Union[str, bool, int]]
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_model_create."""
|
||||
body_include_list = [
|
||||
"id",
|
||||
"display_name",
|
||||
"primary_file_name",
|
||||
"primary_process_id",
|
||||
"description",
|
||||
"metadata_extraction_paths",
|
||||
]
|
||||
body_filtered = {
|
||||
include_item: body[include_item]
|
||||
for include_item in body_include_list
|
||||
if include_item in body
|
||||
}
|
||||
|
||||
if modified_process_group_id is None:
|
||||
raise ApiError(
|
||||
error_code="process_group_id_not_specified",
|
||||
message="Process Model could not be created when process_group_id path param is unspecified",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
unmodified_process_group_id = un_modify_modified_process_model_id(
|
||||
modified_process_group_id
|
||||
)
|
||||
process_group = ProcessModelService.get_process_group(unmodified_process_group_id)
|
||||
if process_group is None:
|
||||
raise ApiError(
|
||||
error_code="process_model_could_not_be_created",
|
||||
message=f"Process Model could not be created from given body because Process Group could not be found: {body}",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
process_model_info = ProcessModelInfo(**body_filtered) # type: ignore
|
||||
if process_model_info is None:
|
||||
raise ApiError(
|
||||
error_code="process_model_could_not_be_created",
|
||||
message=f"Process Model could not be created from given body: {body}",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
ProcessModelService.add_process_model(process_model_info)
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} created process model {process_model_info.id}"
|
||||
)
|
||||
return Response(
|
||||
json.dumps(ProcessModelInfoSchema().dump(process_model_info)),
|
||||
status=201,
|
||||
mimetype="application/json",
|
||||
)
|
||||
|
||||
|
||||
def process_model_delete(
|
||||
modified_process_model_identifier: str,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_model_delete."""
|
||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||
ProcessModelService().process_model_delete(process_model_identifier)
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} deleted process model {process_model_identifier}"
|
||||
)
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_model_update(
|
||||
modified_process_model_identifier: str, body: Dict[str, Union[str, bool, int]]
|
||||
) -> Any:
|
||||
"""Process_model_update."""
|
||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||
body_include_list = [
|
||||
"display_name",
|
||||
"primary_file_name",
|
||||
"primary_process_id",
|
||||
"description",
|
||||
"metadata_extraction_paths",
|
||||
]
|
||||
body_filtered = {
|
||||
include_item: body[include_item]
|
||||
for include_item in body_include_list
|
||||
if include_item in body
|
||||
}
|
||||
|
||||
process_model = get_process_model(process_model_identifier)
|
||||
ProcessModelService.update_process_model(process_model, body_filtered)
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} updated process model {process_model_identifier}"
|
||||
)
|
||||
return ProcessModelInfoSchema().dump(process_model)
|
||||
|
||||
|
||||
def process_model_show(modified_process_model_identifier: str) -> Any:
|
||||
"""Process_model_show."""
|
||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||
process_model = get_process_model(process_model_identifier)
|
||||
files = sorted(
|
||||
SpecFileService.get_files(process_model),
|
||||
key=lambda f: "" if f.name == process_model.primary_file_name else f.sort_index,
|
||||
)
|
||||
process_model.files = files
|
||||
for file in process_model.files:
|
||||
file.references = SpecFileService.get_references_for_file(file, process_model)
|
||||
|
||||
process_model.parent_groups = ProcessModelService.get_parent_group_array(
|
||||
process_model.id
|
||||
)
|
||||
return make_response(jsonify(process_model), 200)
|
||||
|
||||
|
||||
def process_model_move(
|
||||
modified_process_model_identifier: str, new_location: str
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_model_move."""
|
||||
original_process_model_id = un_modify_modified_process_model_id(
|
||||
modified_process_model_identifier
|
||||
)
|
||||
new_process_model = ProcessModelService().process_model_move(
|
||||
original_process_model_id, new_location
|
||||
)
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} moved process model {original_process_model_id} to {new_process_model.id}"
|
||||
)
|
||||
return make_response(jsonify(new_process_model), 200)
|
||||
|
||||
|
||||
def process_model_publish(
|
||||
modified_process_model_identifier: str, branch_to_update: Optional[str] = None
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_model_publish."""
|
||||
if branch_to_update is None:
|
||||
branch_to_update = current_app.config["GIT_BRANCH_TO_PUBLISH_TO"]
|
||||
process_model_identifier = un_modify_modified_process_model_id(
|
||||
modified_process_model_identifier
|
||||
)
|
||||
pr_url = GitService().publish(process_model_identifier, branch_to_update)
|
||||
data = {"ok": True, "pr_url": pr_url}
|
||||
return Response(json.dumps(data), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_model_list(
|
||||
process_group_identifier: Optional[str] = None,
|
||||
recursive: Optional[bool] = False,
|
||||
filter_runnable_by_user: Optional[bool] = False,
|
||||
page: int = 1,
|
||||
per_page: int = 100,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process model list!"""
|
||||
process_models = ProcessModelService.get_process_models(
|
||||
process_group_id=process_group_identifier,
|
||||
recursive=recursive,
|
||||
filter_runnable_by_user=filter_runnable_by_user,
|
||||
)
|
||||
batch = ProcessModelService().get_batch(
|
||||
process_models, page=page, per_page=per_page
|
||||
)
|
||||
pages = len(process_models) // per_page
|
||||
remainder = len(process_models) % per_page
|
||||
if remainder > 0:
|
||||
pages += 1
|
||||
response_json = {
|
||||
"results": ProcessModelInfoSchema(many=True).dump(batch),
|
||||
"pagination": {
|
||||
"count": len(batch),
|
||||
"total": len(process_models),
|
||||
"pages": pages,
|
||||
},
|
||||
}
|
||||
return Response(json.dumps(response_json), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_list() -> Any:
|
||||
"""Returns a list of all known processes.
|
||||
|
||||
|
@ -452,246 +168,6 @@ def process_list() -> Any:
|
|||
return SpecReferenceSchema(many=True).dump(references)
|
||||
|
||||
|
||||
def get_file(modified_process_model_identifier: str, file_name: str) -> Any:
|
||||
"""Get_file."""
|
||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||
process_model = get_process_model(process_model_identifier)
|
||||
files = SpecFileService.get_files(process_model, file_name)
|
||||
if len(files) == 0:
|
||||
raise ApiError(
|
||||
error_code="unknown file",
|
||||
message=f"No information exists for file {file_name}"
|
||||
f" it does not exist in workflow {process_model_identifier}.",
|
||||
status_code=404,
|
||||
)
|
||||
|
||||
file = files[0]
|
||||
file_contents = SpecFileService.get_data(process_model, file.name)
|
||||
file.file_contents = file_contents
|
||||
file.process_model_id = process_model.id
|
||||
# file.process_group_id = process_model.process_group_id
|
||||
return FileSchema().dump(file)
|
||||
|
||||
|
||||
def process_model_file_update(
|
||||
modified_process_model_identifier: str, file_name: str
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_model_file_update."""
|
||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||
process_model = get_process_model(process_model_identifier)
|
||||
|
||||
request_file = get_file_from_request()
|
||||
request_file_contents = request_file.stream.read()
|
||||
if not request_file_contents:
|
||||
raise ApiError(
|
||||
error_code="file_contents_empty",
|
||||
message="Given request file does not have any content",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
SpecFileService.update_file(process_model, file_name, request_file_contents)
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} clicked save for {process_model_identifier}/{file_name}"
|
||||
)
|
||||
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_model_file_delete(
|
||||
modified_process_model_identifier: str, file_name: str
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_model_file_delete."""
|
||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||
process_model = get_process_model(process_model_identifier)
|
||||
try:
|
||||
SpecFileService.delete_file(process_model, file_name)
|
||||
except FileNotFoundError as exception:
|
||||
raise (
|
||||
ApiError(
|
||||
error_code="process_model_file_cannot_be_found",
|
||||
message=f"Process model file cannot be found: {file_name}",
|
||||
status_code=400,
|
||||
)
|
||||
) from exception
|
||||
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} deleted process model file {process_model_identifier}/{file_name}"
|
||||
)
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def add_file(modified_process_model_identifier: str) -> flask.wrappers.Response:
|
||||
"""Add_file."""
|
||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||
process_model = get_process_model(process_model_identifier)
|
||||
request_file = get_file_from_request()
|
||||
if not request_file.filename:
|
||||
raise ApiError(
|
||||
error_code="could_not_get_filename",
|
||||
message="Could not get filename from request",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
file = SpecFileService.add_file(
|
||||
process_model, request_file.filename, request_file.stream.read()
|
||||
)
|
||||
file_contents = SpecFileService.get_data(process_model, file.name)
|
||||
file.file_contents = file_contents
|
||||
file.process_model_id = process_model.id
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} added process model file {process_model_identifier}/{file.name}"
|
||||
)
|
||||
return Response(
|
||||
json.dumps(FileSchema().dump(file)), status=201, mimetype="application/json"
|
||||
)
|
||||
|
||||
|
||||
def process_instance_create(
|
||||
modified_process_model_identifier: str,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Create_process_instance."""
|
||||
process_model_identifier = un_modify_modified_process_model_id(
|
||||
modified_process_model_identifier
|
||||
)
|
||||
process_instance = (
|
||||
ProcessInstanceService.create_process_instance_from_process_model_identifier(
|
||||
process_model_identifier, g.user
|
||||
)
|
||||
)
|
||||
return Response(
|
||||
json.dumps(ProcessInstanceModelSchema().dump(process_instance)),
|
||||
status=201,
|
||||
mimetype="application/json",
|
||||
)
|
||||
|
||||
|
||||
def process_instance_run(
|
||||
modified_process_model_identifier: str,
|
||||
process_instance_id: int,
|
||||
do_engine_steps: bool = True,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_run."""
|
||||
process_instance = ProcessInstanceService().get_process_instance(
|
||||
process_instance_id
|
||||
)
|
||||
if process_instance.status != "not_started":
|
||||
raise ApiError(
|
||||
error_code="process_instance_not_runnable",
|
||||
message=f"Process Instance ({process_instance.id}) is currently running or has already run.",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
processor = ProcessInstanceProcessor(process_instance)
|
||||
|
||||
if do_engine_steps:
|
||||
try:
|
||||
processor.do_engine_steps(save=True)
|
||||
except ApiError as e:
|
||||
ErrorHandlingService().handle_error(processor, e)
|
||||
raise e
|
||||
except Exception as e:
|
||||
ErrorHandlingService().handle_error(processor, e)
|
||||
task = processor.bpmn_process_instance.last_task
|
||||
raise ApiError.from_task(
|
||||
error_code="unknown_exception",
|
||||
message=f"An unknown error occurred. Original error: {e}",
|
||||
status_code=400,
|
||||
task=task,
|
||||
) from e
|
||||
|
||||
if not current_app.config["RUN_BACKGROUND_SCHEDULER"]:
|
||||
MessageService.process_message_instances()
|
||||
|
||||
process_instance_api = ProcessInstanceService.processor_to_process_instance_api(
|
||||
processor
|
||||
)
|
||||
process_instance_data = processor.get_data()
|
||||
process_instance_metadata = ProcessInstanceApiSchema().dump(process_instance_api)
|
||||
process_instance_metadata["data"] = process_instance_data
|
||||
return Response(
|
||||
json.dumps(process_instance_metadata), status=200, mimetype="application/json"
|
||||
)
|
||||
|
||||
|
||||
def process_instance_terminate(
|
||||
process_instance_id: int,
|
||||
modified_process_model_identifier: str,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_run."""
|
||||
process_instance = ProcessInstanceService().get_process_instance(
|
||||
process_instance_id
|
||||
)
|
||||
processor = ProcessInstanceProcessor(process_instance)
|
||||
processor.terminate()
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_instance_suspend(
|
||||
process_instance_id: int,
|
||||
modified_process_model_identifier: str,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_suspend."""
|
||||
process_instance = ProcessInstanceService().get_process_instance(
|
||||
process_instance_id
|
||||
)
|
||||
processor = ProcessInstanceProcessor(process_instance)
|
||||
processor.suspend()
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_instance_resume(
|
||||
process_instance_id: int,
|
||||
modified_process_model_identifier: str,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_resume."""
|
||||
process_instance = ProcessInstanceService().get_process_instance(
|
||||
process_instance_id
|
||||
)
|
||||
processor = ProcessInstanceProcessor(process_instance)
|
||||
processor.resume()
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_instance_log_list(
|
||||
modified_process_model_identifier: str,
|
||||
process_instance_id: int,
|
||||
page: int = 1,
|
||||
per_page: int = 100,
|
||||
detailed: bool = False,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_log_list."""
|
||||
# to make sure the process instance exists
|
||||
process_instance = find_process_instance_by_id_or_raise(process_instance_id)
|
||||
|
||||
log_query = SpiffLoggingModel.query.filter(
|
||||
SpiffLoggingModel.process_instance_id == process_instance.id
|
||||
)
|
||||
if not detailed:
|
||||
log_query = log_query.filter(SpiffLoggingModel.message.in_(["State change to COMPLETED"])) # type: ignore
|
||||
|
||||
logs = (
|
||||
log_query.order_by(SpiffLoggingModel.timestamp.desc()) # type: ignore
|
||||
.join(
|
||||
UserModel, UserModel.id == SpiffLoggingModel.current_user_id, isouter=True
|
||||
) # isouter since if we don't have a user, we still want the log
|
||||
.add_columns(
|
||||
UserModel.username,
|
||||
)
|
||||
.paginate(page=page, per_page=per_page, error_out=False)
|
||||
)
|
||||
|
||||
response_json = {
|
||||
"results": logs.items,
|
||||
"pagination": {
|
||||
"count": len(logs.items),
|
||||
"total": logs.total,
|
||||
"pages": logs.pages,
|
||||
},
|
||||
}
|
||||
|
||||
return make_response(jsonify(response_json), 200)
|
||||
|
||||
|
||||
def message_instance_list(
|
||||
process_instance_id: Optional[int] = None,
|
||||
page: int = 1,
|
||||
|
@ -784,7 +260,7 @@ def message_start(
|
|||
process_instance = None
|
||||
if "process_instance_id" in body:
|
||||
# to make sure we have a valid process_instance_id
|
||||
process_instance = find_process_instance_by_id_or_raise(
|
||||
process_instance = _find_process_instance_by_id_or_raise(
|
||||
body["process_instance_id"]
|
||||
)
|
||||
|
||||
|
@ -837,139 +313,6 @@ def message_start(
|
|||
)
|
||||
|
||||
|
||||
def process_instance_list_for_me(
|
||||
process_model_identifier: Optional[str] = None,
|
||||
page: int = 1,
|
||||
per_page: int = 100,
|
||||
start_from: Optional[int] = None,
|
||||
start_to: Optional[int] = None,
|
||||
end_from: Optional[int] = None,
|
||||
end_to: Optional[int] = None,
|
||||
process_status: Optional[str] = None,
|
||||
user_filter: Optional[bool] = False,
|
||||
report_identifier: Optional[str] = None,
|
||||
report_id: Optional[int] = None,
|
||||
user_group_identifier: Optional[str] = None,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_list_for_me."""
|
||||
return process_instance_list(
|
||||
process_model_identifier=process_model_identifier,
|
||||
page=page,
|
||||
per_page=per_page,
|
||||
start_from=start_from,
|
||||
start_to=start_to,
|
||||
end_from=end_from,
|
||||
end_to=end_to,
|
||||
process_status=process_status,
|
||||
user_filter=user_filter,
|
||||
report_identifier=report_identifier,
|
||||
report_id=report_id,
|
||||
user_group_identifier=user_group_identifier,
|
||||
with_relation_to_me=True,
|
||||
)
|
||||
|
||||
|
||||
def process_instance_list(
|
||||
process_model_identifier: Optional[str] = None,
|
||||
page: int = 1,
|
||||
per_page: int = 100,
|
||||
start_from: Optional[int] = None,
|
||||
start_to: Optional[int] = None,
|
||||
end_from: Optional[int] = None,
|
||||
end_to: Optional[int] = None,
|
||||
process_status: Optional[str] = None,
|
||||
with_relation_to_me: Optional[bool] = None,
|
||||
user_filter: Optional[bool] = False,
|
||||
report_identifier: Optional[str] = None,
|
||||
report_id: Optional[int] = None,
|
||||
user_group_identifier: Optional[str] = None,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_list."""
|
||||
process_instance_report = ProcessInstanceReportService.report_with_identifier(
|
||||
g.user, report_id, report_identifier
|
||||
)
|
||||
|
||||
if user_filter:
|
||||
report_filter = ProcessInstanceReportFilter(
|
||||
process_model_identifier=process_model_identifier,
|
||||
user_group_identifier=user_group_identifier,
|
||||
start_from=start_from,
|
||||
start_to=start_to,
|
||||
end_from=end_from,
|
||||
end_to=end_to,
|
||||
with_relation_to_me=with_relation_to_me,
|
||||
process_status=process_status.split(",") if process_status else None,
|
||||
)
|
||||
else:
|
||||
report_filter = (
|
||||
ProcessInstanceReportService.filter_from_metadata_with_overrides(
|
||||
process_instance_report=process_instance_report,
|
||||
process_model_identifier=process_model_identifier,
|
||||
user_group_identifier=user_group_identifier,
|
||||
start_from=start_from,
|
||||
start_to=start_to,
|
||||
end_from=end_from,
|
||||
end_to=end_to,
|
||||
process_status=process_status,
|
||||
with_relation_to_me=with_relation_to_me,
|
||||
)
|
||||
)
|
||||
|
||||
response_json = ProcessInstanceReportService.run_process_instance_report(
|
||||
report_filter=report_filter,
|
||||
process_instance_report=process_instance_report,
|
||||
page=page,
|
||||
per_page=per_page,
|
||||
user=g.user,
|
||||
)
|
||||
|
||||
return make_response(jsonify(response_json), 200)
|
||||
|
||||
|
||||
def process_instance_report_column_list() -> flask.wrappers.Response:
|
||||
"""Process_instance_report_column_list."""
|
||||
table_columns = ProcessInstanceReportService.builtin_column_options()
|
||||
columns_for_metadata = (
|
||||
db.session.query(ProcessInstanceMetadataModel.key)
|
||||
.order_by(ProcessInstanceMetadataModel.key)
|
||||
.distinct() # type: ignore
|
||||
.all()
|
||||
)
|
||||
columns_for_metadata_strings = [
|
||||
{"Header": i[0], "accessor": i[0], "filterable": True}
|
||||
for i in columns_for_metadata
|
||||
]
|
||||
return make_response(jsonify(table_columns + columns_for_metadata_strings), 200)
|
||||
|
||||
|
||||
def process_instance_show_for_me(
|
||||
modified_process_model_identifier: str,
|
||||
process_instance_id: int,
|
||||
process_identifier: Optional[str] = None,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_show_for_me."""
|
||||
process_instance = _find_process_instance_for_me_or_raise(process_instance_id)
|
||||
return _get_process_instance(
|
||||
process_instance=process_instance,
|
||||
modified_process_model_identifier=modified_process_model_identifier,
|
||||
process_identifier=process_identifier,
|
||||
)
|
||||
|
||||
|
||||
def process_instance_show(
|
||||
modified_process_model_identifier: str,
|
||||
process_instance_id: int,
|
||||
process_identifier: Optional[str] = None,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Create_process_instance."""
|
||||
process_instance = find_process_instance_by_id_or_raise(process_instance_id)
|
||||
return _get_process_instance(
|
||||
process_instance=process_instance,
|
||||
modified_process_model_identifier=modified_process_model_identifier,
|
||||
process_identifier=process_identifier,
|
||||
)
|
||||
|
||||
|
||||
def _get_process_instance(
|
||||
modified_process_model_identifier: str,
|
||||
process_instance: ProcessInstanceModel,
|
||||
|
@ -998,7 +341,7 @@ def _get_process_instance(
|
|||
)
|
||||
name_of_file_with_diagram = spec_reference.file_name
|
||||
else:
|
||||
process_model_with_diagram = get_process_model(process_model_identifier)
|
||||
process_model_with_diagram = _get_process_model(process_model_identifier)
|
||||
if process_model_with_diagram.primary_file_name:
|
||||
name_of_file_with_diagram = process_model_with_diagram.primary_file_name
|
||||
|
||||
|
@ -1021,96 +364,6 @@ def _get_process_instance(
|
|||
return make_response(jsonify(process_instance), 200)
|
||||
|
||||
|
||||
def process_instance_delete(
|
||||
process_instance_id: int, modified_process_model_identifier: str
|
||||
) -> flask.wrappers.Response:
|
||||
"""Create_process_instance."""
|
||||
process_instance = find_process_instance_by_id_or_raise(process_instance_id)
|
||||
|
||||
if not process_instance.has_terminal_status():
|
||||
raise ProcessInstanceCannotBeDeletedError(
|
||||
f"Process instance ({process_instance.id}) cannot be deleted since it does not have a terminal status. "
|
||||
f"Current status is {process_instance.status}."
|
||||
)
|
||||
|
||||
# (Pdb) db.session.delete
|
||||
# <bound method delete of <sqlalchemy.orm.scoping.scoped_session object at 0x103eaab30>>
|
||||
db.session.query(SpiffLoggingModel).filter_by(
|
||||
process_instance_id=process_instance.id
|
||||
).delete()
|
||||
db.session.query(SpiffStepDetailsModel).filter_by(
|
||||
process_instance_id=process_instance.id
|
||||
).delete()
|
||||
db.session.delete(process_instance)
|
||||
db.session.commit()
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_instance_report_list(
|
||||
page: int = 1, per_page: int = 100
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_report_list."""
|
||||
process_instance_reports = ProcessInstanceReportModel.query.filter_by(
|
||||
created_by_id=g.user.id,
|
||||
).all()
|
||||
|
||||
return make_response(jsonify(process_instance_reports), 200)
|
||||
|
||||
|
||||
def process_instance_report_create(body: Dict[str, Any]) -> flask.wrappers.Response:
|
||||
"""Process_instance_report_create."""
|
||||
process_instance_report = ProcessInstanceReportModel.create_report(
|
||||
identifier=body["identifier"],
|
||||
user=g.user,
|
||||
report_metadata=body["report_metadata"],
|
||||
)
|
||||
|
||||
return make_response(jsonify(process_instance_report), 201)
|
||||
|
||||
|
||||
def process_instance_report_update(
|
||||
report_id: int,
|
||||
body: Dict[str, Any],
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_report_create."""
|
||||
process_instance_report = ProcessInstanceReportModel.query.filter_by(
|
||||
id=report_id,
|
||||
created_by_id=g.user.id,
|
||||
).first()
|
||||
if process_instance_report is None:
|
||||
raise ApiError(
|
||||
error_code="unknown_process_instance_report",
|
||||
message="Unknown process instance report",
|
||||
status_code=404,
|
||||
)
|
||||
|
||||
process_instance_report.report_metadata = body["report_metadata"]
|
||||
db.session.commit()
|
||||
|
||||
return make_response(jsonify(process_instance_report), 201)
|
||||
|
||||
|
||||
def process_instance_report_delete(
|
||||
report_id: int,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_report_create."""
|
||||
process_instance_report = ProcessInstanceReportModel.query.filter_by(
|
||||
id=report_id,
|
||||
created_by_id=g.user.id,
|
||||
).first()
|
||||
if process_instance_report is None:
|
||||
raise ApiError(
|
||||
error_code="unknown_process_instance_report",
|
||||
message="Unknown process instance report",
|
||||
status_code=404,
|
||||
)
|
||||
|
||||
db.session.delete(process_instance_report)
|
||||
db.session.commit()
|
||||
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def service_task_list() -> flask.wrappers.Response:
|
||||
"""Service_task_list."""
|
||||
available_connectors = ServiceTaskService.available_connectors()
|
||||
|
@ -1146,42 +399,6 @@ def authentication_callback(
|
|||
)
|
||||
|
||||
|
||||
def process_instance_report_show(
|
||||
report_id: int,
|
||||
page: int = 1,
|
||||
per_page: int = 100,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_report_show."""
|
||||
process_instances = ProcessInstanceModel.query.order_by(
|
||||
ProcessInstanceModel.start_in_seconds.desc(), ProcessInstanceModel.id.desc() # type: ignore
|
||||
).paginate(page=page, per_page=per_page, error_out=False)
|
||||
|
||||
process_instance_report = ProcessInstanceReportModel.query.filter_by(
|
||||
id=report_id,
|
||||
created_by_id=g.user.id,
|
||||
).first()
|
||||
if process_instance_report is None:
|
||||
raise ApiError(
|
||||
error_code="unknown_process_instance_report",
|
||||
message="Unknown process instance report",
|
||||
status_code=404,
|
||||
)
|
||||
|
||||
substitution_variables = request.args.to_dict()
|
||||
result_dict = process_instance_report.generate_report(
|
||||
process_instances.items, substitution_variables
|
||||
)
|
||||
|
||||
# update this if we go back to a database query instead of filtering in memory
|
||||
result_dict["pagination"] = {
|
||||
"count": len(result_dict["results"]),
|
||||
"total": len(result_dict["results"]),
|
||||
"pages": 1,
|
||||
}
|
||||
|
||||
return Response(json.dumps(result_dict), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
# TODO: see comment for before_request
|
||||
# @process_api_blueprint.route("/v1.0/tasks", methods=["GET"])
|
||||
def task_list_my_tasks(page: int = 1, per_page: int = 100) -> flask.wrappers.Response:
|
||||
|
@ -1343,101 +560,9 @@ def get_tasks(
|
|||
return make_response(jsonify(response_json), 200)
|
||||
|
||||
|
||||
def process_instance_task_list_without_task_data_for_me(
|
||||
modified_process_model_identifier: str,
|
||||
process_instance_id: int,
|
||||
all_tasks: bool = False,
|
||||
spiff_step: int = 0,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_task_list_without_task_data_for_me."""
|
||||
process_instance = _find_process_instance_for_me_or_raise(process_instance_id)
|
||||
return process_instance_task_list(
|
||||
modified_process_model_identifier,
|
||||
process_instance,
|
||||
all_tasks,
|
||||
spiff_step,
|
||||
get_task_data=False,
|
||||
)
|
||||
|
||||
|
||||
def process_instance_task_list_without_task_data(
|
||||
modified_process_model_identifier: str,
|
||||
process_instance_id: int,
|
||||
all_tasks: bool = False,
|
||||
spiff_step: int = 0,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_task_list_without_task_data."""
|
||||
process_instance = find_process_instance_by_id_or_raise(process_instance_id)
|
||||
return process_instance_task_list(
|
||||
modified_process_model_identifier,
|
||||
process_instance,
|
||||
all_tasks,
|
||||
spiff_step,
|
||||
get_task_data=False,
|
||||
)
|
||||
|
||||
|
||||
def process_instance_task_list_with_task_data(
|
||||
modified_process_model_identifier: str,
|
||||
process_instance_id: int,
|
||||
all_tasks: bool = False,
|
||||
spiff_step: int = 0,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_task_list_with_task_data."""
|
||||
process_instance = find_process_instance_by_id_or_raise(process_instance_id)
|
||||
return process_instance_task_list(
|
||||
modified_process_model_identifier,
|
||||
process_instance,
|
||||
all_tasks,
|
||||
spiff_step,
|
||||
get_task_data=True,
|
||||
)
|
||||
|
||||
|
||||
def process_instance_task_list(
|
||||
_modified_process_model_identifier: str,
|
||||
process_instance: ProcessInstanceModel,
|
||||
all_tasks: bool = False,
|
||||
spiff_step: int = 0,
|
||||
get_task_data: bool = False,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_task_list."""
|
||||
if spiff_step > 0:
|
||||
step_detail = (
|
||||
db.session.query(SpiffStepDetailsModel)
|
||||
.filter(
|
||||
SpiffStepDetailsModel.process_instance.id == process_instance.id,
|
||||
SpiffStepDetailsModel.spiff_step == spiff_step,
|
||||
)
|
||||
.first()
|
||||
)
|
||||
if step_detail is not None and process_instance.bpmn_json is not None:
|
||||
bpmn_json = json.loads(process_instance.bpmn_json)
|
||||
bpmn_json["tasks"] = step_detail.task_json["tasks"]
|
||||
bpmn_json["subprocesses"] = step_detail.task_json["subprocesses"]
|
||||
process_instance.bpmn_json = json.dumps(bpmn_json)
|
||||
|
||||
processor = ProcessInstanceProcessor(process_instance)
|
||||
|
||||
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)
|
||||
if get_task_data:
|
||||
task.data = spiff_task.data
|
||||
tasks.append(task)
|
||||
|
||||
return make_response(jsonify(tasks), 200)
|
||||
|
||||
|
||||
def task_show(process_instance_id: int, task_id: str) -> flask.wrappers.Response:
|
||||
"""Task_show."""
|
||||
process_instance = find_process_instance_by_id_or_raise(process_instance_id)
|
||||
process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
|
||||
|
||||
if process_instance.status == ProcessInstanceStatus.suspended.value:
|
||||
raise ApiError(
|
||||
|
@ -1446,7 +571,7 @@ def task_show(process_instance_id: int, task_id: str) -> flask.wrappers.Response
|
|||
status_code=400,
|
||||
)
|
||||
|
||||
process_model = get_process_model(
|
||||
process_model = _get_process_model(
|
||||
process_instance.process_model_identifier,
|
||||
)
|
||||
|
||||
|
@ -1542,7 +667,7 @@ def process_data_show(
|
|||
modified_process_model_identifier: str,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_data_show."""
|
||||
process_instance = find_process_instance_by_id_or_raise(process_instance_id)
|
||||
process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
|
||||
processor = ProcessInstanceProcessor(process_instance)
|
||||
all_process_data = processor.get_data()
|
||||
process_data_value = None
|
||||
|
@ -1568,7 +693,7 @@ def task_submit(
|
|||
) -> flask.wrappers.Response:
|
||||
"""Task_submit_user_data."""
|
||||
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)
|
||||
if not process_instance.can_submit_task():
|
||||
raise ApiError(
|
||||
error_code="process_instance_not_runnable",
|
||||
|
@ -1657,7 +782,7 @@ def script_unit_test_create(
|
|||
)
|
||||
|
||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||
process_model = get_process_model(process_model_identifier)
|
||||
process_model = _get_process_model(process_model_identifier)
|
||||
file = SpecFileService.get_files(process_model, process_model.primary_file_name)[0]
|
||||
if file is None:
|
||||
raise ApiError(
|
||||
|
@ -1753,7 +878,7 @@ def script_unit_test_run(
|
|||
return make_response(jsonify(result), 200)
|
||||
|
||||
|
||||
def get_file_from_request() -> Any:
|
||||
def _get_file_from_request() -> Any:
|
||||
"""Get_file_from_request."""
|
||||
request_file = connexion.request.files.get("file")
|
||||
if not request_file:
|
||||
|
@ -1767,7 +892,7 @@ def get_file_from_request() -> Any:
|
|||
|
||||
# process_model_id uses forward slashes on all OSes
|
||||
# this seems to return an object where process_model.id has backslashes on windows
|
||||
def get_process_model(process_model_id: str) -> ProcessModelInfo:
|
||||
def _get_process_model(process_model_id: str) -> ProcessModelInfo:
|
||||
"""Get_process_model."""
|
||||
process_model = None
|
||||
try:
|
||||
|
@ -1798,7 +923,7 @@ def find_principal_or_raise() -> PrincipalModel:
|
|||
return principal # type: ignore
|
||||
|
||||
|
||||
def find_process_instance_by_id_or_raise(
|
||||
def _find_process_instance_by_id_or_raise(
|
||||
process_instance_id: int,
|
||||
) -> ProcessInstanceModel:
|
||||
"""Find_process_instance_by_id_or_raise."""
|
||||
|
@ -2119,3 +1244,8 @@ def _find_process_instance_for_me_or_raise(
|
|||
)
|
||||
|
||||
return process_instance
|
||||
|
||||
|
||||
def _un_modify_modified_process_model_id(modified_process_model_identifier: str) -> str:
|
||||
"""Un_modify_modified_process_model_id."""
|
||||
return modified_process_model_identifier.replace(":", "/")
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
"""APIs for dealing with process groups, process models, and process instances."""
|
||||
import json
|
||||
from typing import Any
|
||||
from typing import Optional
|
||||
from typing import TypedDict
|
||||
|
||||
import flask.wrappers
|
||||
from flask import Blueprint
|
||||
from flask import g
|
||||
from flask import jsonify
|
||||
from flask import make_response
|
||||
from flask.wrappers import Response
|
||||
from flask_bpmn.api.api_error import ApiError
|
||||
|
||||
from spiffworkflow_backend.exceptions.process_entity_not_found_error import (
|
||||
ProcessEntityNotFoundError,
|
||||
)
|
||||
from spiffworkflow_backend.models.process_group import ProcessGroup
|
||||
from spiffworkflow_backend.models.process_group import ProcessGroupSchema
|
||||
from spiffworkflow_backend.services.process_model_service import ProcessModelService
|
||||
from spiffworkflow_backend.routes.process_api_blueprint import _commit_and_push_to_git, _un_modify_modified_process_model_id
|
||||
|
||||
|
||||
def process_group_create(body: dict) -> flask.wrappers.Response:
|
||||
"""Add_process_group."""
|
||||
process_group = ProcessGroup(**body)
|
||||
ProcessModelService.add_process_group(process_group)
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} added process group {process_group.id}"
|
||||
)
|
||||
return make_response(jsonify(process_group), 201)
|
||||
|
||||
|
||||
def process_group_delete(modified_process_group_id: str) -> flask.wrappers.Response:
|
||||
"""Process_group_delete."""
|
||||
process_group_id = _un_modify_modified_process_model_id(modified_process_group_id)
|
||||
ProcessModelService().process_group_delete(process_group_id)
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} deleted process group {process_group_id}"
|
||||
)
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_group_update(
|
||||
modified_process_group_id: str, body: dict
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process Group Update."""
|
||||
body_include_list = ["display_name", "description"]
|
||||
body_filtered = {
|
||||
include_item: body[include_item]
|
||||
for include_item in body_include_list
|
||||
if include_item in body
|
||||
}
|
||||
|
||||
process_group_id = _un_modify_modified_process_model_id(modified_process_group_id)
|
||||
process_group = ProcessGroup(id=process_group_id, **body_filtered)
|
||||
ProcessModelService.update_process_group(process_group)
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} updated process group {process_group_id}"
|
||||
)
|
||||
return make_response(jsonify(process_group), 200)
|
||||
|
||||
|
||||
def process_group_list(
|
||||
process_group_identifier: Optional[str] = None, page: int = 1, per_page: int = 100
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_group_list."""
|
||||
if process_group_identifier is not None:
|
||||
process_groups = ProcessModelService.get_process_groups(
|
||||
process_group_identifier
|
||||
)
|
||||
else:
|
||||
process_groups = ProcessModelService.get_process_groups()
|
||||
batch = ProcessModelService().get_batch(
|
||||
items=process_groups, page=page, per_page=per_page
|
||||
)
|
||||
pages = len(process_groups) // per_page
|
||||
remainder = len(process_groups) % per_page
|
||||
if remainder > 0:
|
||||
pages += 1
|
||||
|
||||
response_json = {
|
||||
"results": ProcessGroupSchema(many=True).dump(batch),
|
||||
"pagination": {
|
||||
"count": len(batch),
|
||||
"total": len(process_groups),
|
||||
"pages": pages,
|
||||
},
|
||||
}
|
||||
return Response(json.dumps(response_json), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_group_show(
|
||||
modified_process_group_id: str,
|
||||
) -> Any:
|
||||
"""Process_group_show."""
|
||||
process_group_id = _un_modify_modified_process_model_id(modified_process_group_id)
|
||||
try:
|
||||
process_group = ProcessModelService.get_process_group(process_group_id)
|
||||
except ProcessEntityNotFoundError as exception:
|
||||
raise (
|
||||
ApiError(
|
||||
error_code="process_group_cannot_be_found",
|
||||
message=f"Process group cannot be found: {process_group_id}",
|
||||
status_code=400,
|
||||
)
|
||||
) from exception
|
||||
|
||||
process_group.parent_groups = ProcessModelService.get_parent_group_array(
|
||||
process_group.id
|
||||
)
|
||||
return make_response(jsonify(process_group), 200)
|
||||
|
||||
|
||||
def process_group_move(
|
||||
modified_process_group_identifier: str, new_location: str
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_group_move."""
|
||||
original_process_group_id = _un_modify_modified_process_model_id(
|
||||
modified_process_group_identifier
|
||||
)
|
||||
new_process_group = ProcessModelService().process_group_move(
|
||||
original_process_group_id, new_location
|
||||
)
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} moved process group {original_process_group_id} to {new_process_group.id}"
|
||||
)
|
||||
return make_response(jsonify(new_process_group), 200)
|
|
@ -0,0 +1,544 @@
|
|||
"""APIs for dealing with process groups, process models, and process instances."""
|
||||
from spiffworkflow_backend.routes.process_api_blueprint import _find_process_instance_for_me_or_raise, _find_process_instance_by_id_or_raise, _un_modify_modified_process_model_id, _get_process_instance
|
||||
import json
|
||||
from typing import Any
|
||||
from typing import Dict
|
||||
from typing import Optional
|
||||
|
||||
import flask.wrappers
|
||||
from flask import current_app
|
||||
from flask import g
|
||||
from flask import jsonify
|
||||
from flask import make_response
|
||||
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.task import TaskState
|
||||
|
||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceApiSchema
|
||||
from spiffworkflow_backend.models.process_instance import (
|
||||
ProcessInstanceCannotBeDeletedError,
|
||||
)
|
||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModelSchema
|
||||
from spiffworkflow_backend.models.process_instance_metadata import (
|
||||
ProcessInstanceMetadataModel,
|
||||
)
|
||||
from spiffworkflow_backend.models.process_instance_report import (
|
||||
ProcessInstanceReportModel,
|
||||
)
|
||||
from spiffworkflow_backend.models.spiff_logging import SpiffLoggingModel
|
||||
from spiffworkflow_backend.models.spiff_step_details import SpiffStepDetailsModel
|
||||
from spiffworkflow_backend.models.user import UserModel
|
||||
from spiffworkflow_backend.services.error_handling_service import ErrorHandlingService
|
||||
from spiffworkflow_backend.services.message_service import MessageService
|
||||
from spiffworkflow_backend.services.process_instance_processor import (
|
||||
ProcessInstanceProcessor,
|
||||
)
|
||||
from spiffworkflow_backend.services.process_instance_report_service import (
|
||||
ProcessInstanceReportFilter,
|
||||
)
|
||||
from spiffworkflow_backend.services.process_instance_report_service import (
|
||||
ProcessInstanceReportService,
|
||||
)
|
||||
from spiffworkflow_backend.services.process_instance_service import (
|
||||
ProcessInstanceService,
|
||||
)
|
||||
|
||||
|
||||
def process_instance_create(
|
||||
modified_process_model_identifier: str,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Create_process_instance."""
|
||||
process_model_identifier = _un_modify_modified_process_model_id(
|
||||
modified_process_model_identifier
|
||||
)
|
||||
process_instance = (
|
||||
ProcessInstanceService.create_process_instance_from_process_model_identifier(
|
||||
process_model_identifier, g.user
|
||||
)
|
||||
)
|
||||
return Response(
|
||||
json.dumps(ProcessInstanceModelSchema().dump(process_instance)),
|
||||
status=201,
|
||||
mimetype="application/json",
|
||||
)
|
||||
|
||||
|
||||
def process_instance_run(
|
||||
modified_process_model_identifier: str,
|
||||
process_instance_id: int,
|
||||
do_engine_steps: bool = True,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_run."""
|
||||
process_instance = ProcessInstanceService().get_process_instance(
|
||||
process_instance_id
|
||||
)
|
||||
if process_instance.status != "not_started":
|
||||
raise ApiError(
|
||||
error_code="process_instance_not_runnable",
|
||||
message=f"Process Instance ({process_instance.id}) is currently running or has already run.",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
processor = ProcessInstanceProcessor(process_instance)
|
||||
|
||||
if do_engine_steps:
|
||||
try:
|
||||
processor.do_engine_steps(save=True)
|
||||
except ApiError as e:
|
||||
ErrorHandlingService().handle_error(processor, e)
|
||||
raise e
|
||||
except Exception as e:
|
||||
ErrorHandlingService().handle_error(processor, e)
|
||||
task = processor.bpmn_process_instance.last_task
|
||||
raise ApiError.from_task(
|
||||
error_code="unknown_exception",
|
||||
message=f"An unknown error occurred. Original error: {e}",
|
||||
status_code=400,
|
||||
task=task,
|
||||
) from e
|
||||
|
||||
if not current_app.config["RUN_BACKGROUND_SCHEDULER"]:
|
||||
MessageService.process_message_instances()
|
||||
|
||||
process_instance_api = ProcessInstanceService.processor_to_process_instance_api(
|
||||
processor
|
||||
)
|
||||
process_instance_data = processor.get_data()
|
||||
process_instance_metadata = ProcessInstanceApiSchema().dump(process_instance_api)
|
||||
process_instance_metadata["data"] = process_instance_data
|
||||
return Response(
|
||||
json.dumps(process_instance_metadata), status=200, mimetype="application/json"
|
||||
)
|
||||
|
||||
|
||||
def process_instance_terminate(
|
||||
process_instance_id: int,
|
||||
modified_process_model_identifier: str,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_run."""
|
||||
process_instance = ProcessInstanceService().get_process_instance(
|
||||
process_instance_id
|
||||
)
|
||||
processor = ProcessInstanceProcessor(process_instance)
|
||||
processor.terminate()
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_instance_suspend(
|
||||
process_instance_id: int,
|
||||
modified_process_model_identifier: str,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_suspend."""
|
||||
process_instance = ProcessInstanceService().get_process_instance(
|
||||
process_instance_id
|
||||
)
|
||||
processor = ProcessInstanceProcessor(process_instance)
|
||||
processor.suspend()
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_instance_resume(
|
||||
process_instance_id: int,
|
||||
modified_process_model_identifier: str,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_resume."""
|
||||
process_instance = ProcessInstanceService().get_process_instance(
|
||||
process_instance_id
|
||||
)
|
||||
processor = ProcessInstanceProcessor(process_instance)
|
||||
processor.resume()
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_instance_log_list(
|
||||
modified_process_model_identifier: str,
|
||||
process_instance_id: int,
|
||||
page: int = 1,
|
||||
per_page: int = 100,
|
||||
detailed: bool = False,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_log_list."""
|
||||
# to make sure the process instance exists
|
||||
process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
|
||||
|
||||
log_query = SpiffLoggingModel.query.filter(
|
||||
SpiffLoggingModel.process_instance_id == process_instance.id
|
||||
)
|
||||
if not detailed:
|
||||
log_query = log_query.filter(SpiffLoggingModel.message.in_(["State change to COMPLETED"])) # type: ignore
|
||||
|
||||
logs = (
|
||||
log_query.order_by(SpiffLoggingModel.timestamp.desc()) # type: ignore
|
||||
.join(
|
||||
UserModel, UserModel.id == SpiffLoggingModel.current_user_id, isouter=True
|
||||
) # isouter since if we don't have a user, we still want the log
|
||||
.add_columns(
|
||||
UserModel.username,
|
||||
)
|
||||
.paginate(page=page, per_page=per_page, error_out=False)
|
||||
)
|
||||
|
||||
response_json = {
|
||||
"results": logs.items,
|
||||
"pagination": {
|
||||
"count": len(logs.items),
|
||||
"total": logs.total,
|
||||
"pages": logs.pages,
|
||||
},
|
||||
}
|
||||
|
||||
return make_response(jsonify(response_json), 200)
|
||||
|
||||
|
||||
def process_instance_list_for_me(
|
||||
process_model_identifier: Optional[str] = None,
|
||||
page: int = 1,
|
||||
per_page: int = 100,
|
||||
start_from: Optional[int] = None,
|
||||
start_to: Optional[int] = None,
|
||||
end_from: Optional[int] = None,
|
||||
end_to: Optional[int] = None,
|
||||
process_status: Optional[str] = None,
|
||||
user_filter: Optional[bool] = False,
|
||||
report_identifier: Optional[str] = None,
|
||||
report_id: Optional[int] = None,
|
||||
user_group_identifier: Optional[str] = None,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_list_for_me."""
|
||||
return process_instance_list(
|
||||
process_model_identifier=process_model_identifier,
|
||||
page=page,
|
||||
per_page=per_page,
|
||||
start_from=start_from,
|
||||
start_to=start_to,
|
||||
end_from=end_from,
|
||||
end_to=end_to,
|
||||
process_status=process_status,
|
||||
user_filter=user_filter,
|
||||
report_identifier=report_identifier,
|
||||
report_id=report_id,
|
||||
user_group_identifier=user_group_identifier,
|
||||
with_relation_to_me=True,
|
||||
)
|
||||
|
||||
|
||||
def process_instance_list(
|
||||
process_model_identifier: Optional[str] = None,
|
||||
page: int = 1,
|
||||
per_page: int = 100,
|
||||
start_from: Optional[int] = None,
|
||||
start_to: Optional[int] = None,
|
||||
end_from: Optional[int] = None,
|
||||
end_to: Optional[int] = None,
|
||||
process_status: Optional[str] = None,
|
||||
with_relation_to_me: Optional[bool] = None,
|
||||
user_filter: Optional[bool] = False,
|
||||
report_identifier: Optional[str] = None,
|
||||
report_id: Optional[int] = None,
|
||||
user_group_identifier: Optional[str] = None,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_list."""
|
||||
process_instance_report = ProcessInstanceReportService.report_with_identifier(
|
||||
g.user, report_id, report_identifier
|
||||
)
|
||||
|
||||
if user_filter:
|
||||
report_filter = ProcessInstanceReportFilter(
|
||||
process_model_identifier=process_model_identifier,
|
||||
user_group_identifier=user_group_identifier,
|
||||
start_from=start_from,
|
||||
start_to=start_to,
|
||||
end_from=end_from,
|
||||
end_to=end_to,
|
||||
with_relation_to_me=with_relation_to_me,
|
||||
process_status=process_status.split(",") if process_status else None,
|
||||
)
|
||||
else:
|
||||
report_filter = (
|
||||
ProcessInstanceReportService.filter_from_metadata_with_overrides(
|
||||
process_instance_report=process_instance_report,
|
||||
process_model_identifier=process_model_identifier,
|
||||
user_group_identifier=user_group_identifier,
|
||||
start_from=start_from,
|
||||
start_to=start_to,
|
||||
end_from=end_from,
|
||||
end_to=end_to,
|
||||
process_status=process_status,
|
||||
with_relation_to_me=with_relation_to_me,
|
||||
)
|
||||
)
|
||||
|
||||
response_json = ProcessInstanceReportService.run_process_instance_report(
|
||||
report_filter=report_filter,
|
||||
process_instance_report=process_instance_report,
|
||||
page=page,
|
||||
per_page=per_page,
|
||||
user=g.user,
|
||||
)
|
||||
|
||||
return make_response(jsonify(response_json), 200)
|
||||
|
||||
|
||||
def process_instance_report_column_list() -> flask.wrappers.Response:
|
||||
"""Process_instance_report_column_list."""
|
||||
table_columns = ProcessInstanceReportService.builtin_column_options()
|
||||
columns_for_metadata = (
|
||||
db.session.query(ProcessInstanceMetadataModel.key)
|
||||
.order_by(ProcessInstanceMetadataModel.key)
|
||||
.distinct() # type: ignore
|
||||
.all()
|
||||
)
|
||||
columns_for_metadata_strings = [
|
||||
{"Header": i[0], "accessor": i[0], "filterable": True}
|
||||
for i in columns_for_metadata
|
||||
]
|
||||
return make_response(jsonify(table_columns + columns_for_metadata_strings), 200)
|
||||
|
||||
|
||||
def process_instance_show_for_me(
|
||||
modified_process_model_identifier: str,
|
||||
process_instance_id: int,
|
||||
process_identifier: Optional[str] = None,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_show_for_me."""
|
||||
process_instance = _find_process_instance_for_me_or_raise(process_instance_id)
|
||||
return _get_process_instance(
|
||||
process_instance=process_instance,
|
||||
modified_process_model_identifier=modified_process_model_identifier,
|
||||
process_identifier=process_identifier,
|
||||
)
|
||||
|
||||
|
||||
def process_instance_show(
|
||||
modified_process_model_identifier: str,
|
||||
process_instance_id: int,
|
||||
process_identifier: Optional[str] = None,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Create_process_instance."""
|
||||
process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
|
||||
return _get_process_instance(
|
||||
process_instance=process_instance,
|
||||
modified_process_model_identifier=modified_process_model_identifier,
|
||||
process_identifier=process_identifier,
|
||||
)
|
||||
|
||||
|
||||
def process_instance_delete(
|
||||
process_instance_id: int, modified_process_model_identifier: str
|
||||
) -> flask.wrappers.Response:
|
||||
"""Create_process_instance."""
|
||||
process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
|
||||
|
||||
if not process_instance.has_terminal_status():
|
||||
raise ProcessInstanceCannotBeDeletedError(
|
||||
f"Process instance ({process_instance.id}) cannot be deleted since it does not have a terminal status. "
|
||||
f"Current status is {process_instance.status}."
|
||||
)
|
||||
|
||||
# (Pdb) db.session.delete
|
||||
# <bound method delete of <sqlalchemy.orm.scoping.scoped_session object at 0x103eaab30>>
|
||||
db.session.query(SpiffLoggingModel).filter_by(
|
||||
process_instance_id=process_instance.id
|
||||
).delete()
|
||||
db.session.query(SpiffStepDetailsModel).filter_by(
|
||||
process_instance_id=process_instance.id
|
||||
).delete()
|
||||
db.session.delete(process_instance)
|
||||
db.session.commit()
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_instance_report_list(
|
||||
page: int = 1, per_page: int = 100
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_report_list."""
|
||||
process_instance_reports = ProcessInstanceReportModel.query.filter_by(
|
||||
created_by_id=g.user.id,
|
||||
).all()
|
||||
|
||||
return make_response(jsonify(process_instance_reports), 200)
|
||||
|
||||
|
||||
def process_instance_report_create(body: Dict[str, Any]) -> flask.wrappers.Response:
|
||||
"""Process_instance_report_create."""
|
||||
process_instance_report = ProcessInstanceReportModel.create_report(
|
||||
identifier=body["identifier"],
|
||||
user=g.user,
|
||||
report_metadata=body["report_metadata"],
|
||||
)
|
||||
|
||||
return make_response(jsonify(process_instance_report), 201)
|
||||
|
||||
|
||||
def process_instance_report_update(
|
||||
report_id: int,
|
||||
body: Dict[str, Any],
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_report_create."""
|
||||
process_instance_report = ProcessInstanceReportModel.query.filter_by(
|
||||
id=report_id,
|
||||
created_by_id=g.user.id,
|
||||
).first()
|
||||
if process_instance_report is None:
|
||||
raise ApiError(
|
||||
error_code="unknown_process_instance_report",
|
||||
message="Unknown process instance report",
|
||||
status_code=404,
|
||||
)
|
||||
|
||||
process_instance_report.report_metadata = body["report_metadata"]
|
||||
db.session.commit()
|
||||
|
||||
return make_response(jsonify(process_instance_report), 201)
|
||||
|
||||
|
||||
def process_instance_report_delete(
|
||||
report_id: int,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_report_create."""
|
||||
process_instance_report = ProcessInstanceReportModel.query.filter_by(
|
||||
id=report_id,
|
||||
created_by_id=g.user.id,
|
||||
).first()
|
||||
if process_instance_report is None:
|
||||
raise ApiError(
|
||||
error_code="unknown_process_instance_report",
|
||||
message="Unknown process instance report",
|
||||
status_code=404,
|
||||
)
|
||||
|
||||
db.session.delete(process_instance_report)
|
||||
db.session.commit()
|
||||
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_instance_report_show(
|
||||
report_id: int,
|
||||
page: int = 1,
|
||||
per_page: int = 100,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_report_show."""
|
||||
process_instances = ProcessInstanceModel.query.order_by(
|
||||
ProcessInstanceModel.start_in_seconds.desc(), ProcessInstanceModel.id.desc() # type: ignore
|
||||
).paginate(page=page, per_page=per_page, error_out=False)
|
||||
|
||||
process_instance_report = ProcessInstanceReportModel.query.filter_by(
|
||||
id=report_id,
|
||||
created_by_id=g.user.id,
|
||||
).first()
|
||||
if process_instance_report is None:
|
||||
raise ApiError(
|
||||
error_code="unknown_process_instance_report",
|
||||
message="Unknown process instance report",
|
||||
status_code=404,
|
||||
)
|
||||
|
||||
substitution_variables = request.args.to_dict()
|
||||
result_dict = process_instance_report.generate_report(
|
||||
process_instances.items, substitution_variables
|
||||
)
|
||||
|
||||
# update this if we go back to a database query instead of filtering in memory
|
||||
result_dict["pagination"] = {
|
||||
"count": len(result_dict["results"]),
|
||||
"total": len(result_dict["results"]),
|
||||
"pages": 1,
|
||||
}
|
||||
|
||||
return Response(json.dumps(result_dict), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_instance_task_list_without_task_data_for_me(
|
||||
modified_process_model_identifier: str,
|
||||
process_instance_id: int,
|
||||
all_tasks: bool = False,
|
||||
spiff_step: int = 0,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_task_list_without_task_data_for_me."""
|
||||
process_instance = _find_process_instance_for_me_or_raise(process_instance_id)
|
||||
return process_instance_task_list(
|
||||
modified_process_model_identifier,
|
||||
process_instance,
|
||||
all_tasks,
|
||||
spiff_step,
|
||||
get_task_data=False,
|
||||
)
|
||||
|
||||
|
||||
def process_instance_task_list_without_task_data(
|
||||
modified_process_model_identifier: str,
|
||||
process_instance_id: int,
|
||||
all_tasks: bool = False,
|
||||
spiff_step: int = 0,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_task_list_without_task_data."""
|
||||
process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
|
||||
return process_instance_task_list(
|
||||
modified_process_model_identifier,
|
||||
process_instance,
|
||||
all_tasks,
|
||||
spiff_step,
|
||||
get_task_data=False,
|
||||
)
|
||||
|
||||
|
||||
def process_instance_task_list_with_task_data(
|
||||
modified_process_model_identifier: str,
|
||||
process_instance_id: int,
|
||||
all_tasks: bool = False,
|
||||
spiff_step: int = 0,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_task_list_with_task_data."""
|
||||
process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
|
||||
return process_instance_task_list(
|
||||
modified_process_model_identifier,
|
||||
process_instance,
|
||||
all_tasks,
|
||||
spiff_step,
|
||||
get_task_data=True,
|
||||
)
|
||||
|
||||
|
||||
def process_instance_task_list(
|
||||
_modified_process_model_identifier: str,
|
||||
process_instance: ProcessInstanceModel,
|
||||
all_tasks: bool = False,
|
||||
spiff_step: int = 0,
|
||||
get_task_data: bool = False,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_instance_task_list."""
|
||||
if spiff_step > 0:
|
||||
step_detail = (
|
||||
db.session.query(SpiffStepDetailsModel)
|
||||
.filter(
|
||||
SpiffStepDetailsModel.process_instance.id == process_instance.id,
|
||||
SpiffStepDetailsModel.spiff_step == spiff_step,
|
||||
)
|
||||
.first()
|
||||
)
|
||||
if step_detail is not None and process_instance.bpmn_json is not None:
|
||||
bpmn_json = json.loads(process_instance.bpmn_json)
|
||||
bpmn_json["tasks"] = step_detail.task_json["tasks"]
|
||||
bpmn_json["subprocesses"] = step_detail.task_json["subprocesses"]
|
||||
process_instance.bpmn_json = json.dumps(bpmn_json)
|
||||
|
||||
processor = ProcessInstanceProcessor(process_instance)
|
||||
|
||||
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)
|
||||
if get_task_data:
|
||||
task.data = spiff_task.data
|
||||
tasks.append(task)
|
||||
|
||||
return make_response(jsonify(tasks), 200)
|
|
@ -0,0 +1,292 @@
|
|||
"""APIs for dealing with process groups, process models, and process instances."""
|
||||
import json
|
||||
from spiffworkflow_backend.routes.process_api_blueprint import _commit_and_push_to_git, _un_modify_modified_process_model_id, _get_process_model, _get_file_from_request
|
||||
from typing import Any
|
||||
from typing import Dict
|
||||
from typing import Optional
|
||||
from typing import Union
|
||||
|
||||
import flask.wrappers
|
||||
from flask import current_app
|
||||
from flask import g
|
||||
from flask import jsonify
|
||||
from flask import make_response
|
||||
from flask.wrappers import Response
|
||||
from flask_bpmn.api.api_error import ApiError
|
||||
|
||||
from spiffworkflow_backend.models.file import FileSchema
|
||||
from spiffworkflow_backend.models.process_model import ProcessModelInfo
|
||||
from spiffworkflow_backend.models.process_model import ProcessModelInfoSchema
|
||||
from spiffworkflow_backend.services.git_service import MissingGitConfigsError
|
||||
from spiffworkflow_backend.services.git_service import GitService
|
||||
from spiffworkflow_backend.services.process_model_service import ProcessModelService
|
||||
from spiffworkflow_backend.services.spec_file_service import SpecFileService
|
||||
|
||||
|
||||
def process_model_create(
|
||||
modified_process_group_id: str, body: Dict[str, Union[str, bool, int]]
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_model_create."""
|
||||
body_include_list = [
|
||||
"id",
|
||||
"display_name",
|
||||
"primary_file_name",
|
||||
"primary_process_id",
|
||||
"description",
|
||||
"metadata_extraction_paths",
|
||||
]
|
||||
body_filtered = {
|
||||
include_item: body[include_item]
|
||||
for include_item in body_include_list
|
||||
if include_item in body
|
||||
}
|
||||
|
||||
if modified_process_group_id is None:
|
||||
raise ApiError(
|
||||
error_code="process_group_id_not_specified",
|
||||
message="Process Model could not be created when process_group_id path param is unspecified",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
unmodified_process_group_id = _un_modify_modified_process_model_id(
|
||||
modified_process_group_id
|
||||
)
|
||||
process_group = ProcessModelService.get_process_group(unmodified_process_group_id)
|
||||
if process_group is None:
|
||||
raise ApiError(
|
||||
error_code="process_model_could_not_be_created",
|
||||
message=f"Process Model could not be created from given body because Process Group could not be found: {body}",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
process_model_info = ProcessModelInfo(**body_filtered) # type: ignore
|
||||
if process_model_info is None:
|
||||
raise ApiError(
|
||||
error_code="process_model_could_not_be_created",
|
||||
message=f"Process Model could not be created from given body: {body}",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
ProcessModelService.add_process_model(process_model_info)
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} created process model {process_model_info.id}"
|
||||
)
|
||||
return Response(
|
||||
json.dumps(ProcessModelInfoSchema().dump(process_model_info)),
|
||||
status=201,
|
||||
mimetype="application/json",
|
||||
)
|
||||
|
||||
|
||||
def process_model_delete(
|
||||
modified_process_model_identifier: str,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_model_delete."""
|
||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||
ProcessModelService().process_model_delete(process_model_identifier)
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} deleted process model {process_model_identifier}"
|
||||
)
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_model_update(
|
||||
modified_process_model_identifier: str, body: Dict[str, Union[str, bool, int]]
|
||||
) -> Any:
|
||||
"""Process_model_update."""
|
||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||
body_include_list = [
|
||||
"display_name",
|
||||
"primary_file_name",
|
||||
"primary_process_id",
|
||||
"description",
|
||||
"metadata_extraction_paths",
|
||||
]
|
||||
body_filtered = {
|
||||
include_item: body[include_item]
|
||||
for include_item in body_include_list
|
||||
if include_item in body
|
||||
}
|
||||
|
||||
process_model = _get_process_model(process_model_identifier)
|
||||
ProcessModelService.update_process_model(process_model, body_filtered)
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} updated process model {process_model_identifier}"
|
||||
)
|
||||
return ProcessModelInfoSchema().dump(process_model)
|
||||
|
||||
|
||||
def process_model_show(modified_process_model_identifier: str) -> Any:
|
||||
"""Process_model_show."""
|
||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||
process_model = _get_process_model(process_model_identifier)
|
||||
files = sorted(
|
||||
SpecFileService.get_files(process_model),
|
||||
key=lambda f: "" if f.name == process_model.primary_file_name else f.sort_index,
|
||||
)
|
||||
process_model.files = files
|
||||
for file in process_model.files:
|
||||
file.references = SpecFileService.get_references_for_file(file, process_model)
|
||||
|
||||
process_model.parent_groups = ProcessModelService.get_parent_group_array(
|
||||
process_model.id
|
||||
)
|
||||
return make_response(jsonify(process_model), 200)
|
||||
|
||||
|
||||
def process_model_move(
|
||||
modified_process_model_identifier: str, new_location: str
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_model_move."""
|
||||
original_process_model_id = _un_modify_modified_process_model_id(
|
||||
modified_process_model_identifier
|
||||
)
|
||||
new_process_model = ProcessModelService().process_model_move(
|
||||
original_process_model_id, new_location
|
||||
)
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} moved process model {original_process_model_id} to {new_process_model.id}"
|
||||
)
|
||||
return make_response(jsonify(new_process_model), 200)
|
||||
|
||||
|
||||
def process_model_publish(
|
||||
modified_process_model_identifier: str, branch_to_update: Optional[str] = None
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_model_publish."""
|
||||
if branch_to_update is None:
|
||||
branch_to_update = current_app.config["GIT_BRANCH_TO_PUBLISH_TO"]
|
||||
if branch_to_update is None:
|
||||
raise MissingGitConfigsError(
|
||||
"Missing config for GIT_BRANCH_TO_PUBLISH_TO. "
|
||||
"This is required for publishing process models"
|
||||
)
|
||||
process_model_identifier = _un_modify_modified_process_model_id(
|
||||
modified_process_model_identifier
|
||||
)
|
||||
pr_url = GitService().publish(process_model_identifier, branch_to_update)
|
||||
data = {"ok": True, "pr_url": pr_url}
|
||||
return Response(json.dumps(data), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_model_list(
|
||||
process_group_identifier: Optional[str] = None,
|
||||
recursive: Optional[bool] = False,
|
||||
filter_runnable_by_user: Optional[bool] = False,
|
||||
page: int = 1,
|
||||
per_page: int = 100,
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process model list!"""
|
||||
process_models = ProcessModelService.get_process_models(
|
||||
process_group_id=process_group_identifier,
|
||||
recursive=recursive,
|
||||
filter_runnable_by_user=filter_runnable_by_user,
|
||||
)
|
||||
batch = ProcessModelService().get_batch(
|
||||
process_models, page=page, per_page=per_page
|
||||
)
|
||||
pages = len(process_models) // per_page
|
||||
remainder = len(process_models) % per_page
|
||||
if remainder > 0:
|
||||
pages += 1
|
||||
response_json = {
|
||||
"results": ProcessModelInfoSchema(many=True).dump(batch),
|
||||
"pagination": {
|
||||
"count": len(batch),
|
||||
"total": len(process_models),
|
||||
"pages": pages,
|
||||
},
|
||||
}
|
||||
return Response(json.dumps(response_json), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_model_file_update(
|
||||
modified_process_model_identifier: str, file_name: str
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_model_file_update."""
|
||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||
process_model = _get_process_model(process_model_identifier)
|
||||
|
||||
request_file = _get_file_from_request()
|
||||
request_file_contents = request_file.stream.read()
|
||||
if not request_file_contents:
|
||||
raise ApiError(
|
||||
error_code="file_contents_empty",
|
||||
message="Given request file does not have any content",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
SpecFileService.update_file(process_model, file_name, request_file_contents)
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} clicked save for {process_model_identifier}/{file_name}"
|
||||
)
|
||||
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_model_file_delete(
|
||||
modified_process_model_identifier: str, file_name: str
|
||||
) -> flask.wrappers.Response:
|
||||
"""Process_model_file_delete."""
|
||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||
process_model = _get_process_model(process_model_identifier)
|
||||
try:
|
||||
SpecFileService.delete_file(process_model, file_name)
|
||||
except FileNotFoundError as exception:
|
||||
raise (
|
||||
ApiError(
|
||||
error_code="process_model_file_cannot_be_found",
|
||||
message=f"Process model file cannot be found: {file_name}",
|
||||
status_code=400,
|
||||
)
|
||||
) from exception
|
||||
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} deleted process model file {process_model_identifier}/{file_name}"
|
||||
)
|
||||
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
|
||||
|
||||
|
||||
def process_model_file_create(modified_process_model_identifier: str) -> flask.wrappers.Response:
|
||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||
process_model = _get_process_model(process_model_identifier)
|
||||
request_file = _get_file_from_request()
|
||||
if not request_file.filename:
|
||||
raise ApiError(
|
||||
error_code="could_not_get_filename",
|
||||
message="Could not get filename from request",
|
||||
status_code=400,
|
||||
)
|
||||
|
||||
file = SpecFileService.add_file(
|
||||
process_model, request_file.filename, request_file.stream.read()
|
||||
)
|
||||
file_contents = SpecFileService.get_data(process_model, file.name)
|
||||
file.file_contents = file_contents
|
||||
file.process_model_id = process_model.id
|
||||
_commit_and_push_to_git(
|
||||
f"User: {g.user.username} added process model file {process_model_identifier}/{file.name}"
|
||||
)
|
||||
return Response(
|
||||
json.dumps(FileSchema().dump(file)), status=201, mimetype="application/json"
|
||||
)
|
||||
|
||||
|
||||
def process_model_file_show(modified_process_model_identifier: str, file_name: str) -> Any:
|
||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||
process_model = _get_process_model(process_model_identifier)
|
||||
files = SpecFileService.get_files(process_model, file_name)
|
||||
if len(files) == 0:
|
||||
raise ApiError(
|
||||
error_code="unknown file",
|
||||
message=f"No information exists for file {file_name}"
|
||||
f" it does not exist in workflow {process_model_identifier}.",
|
||||
status_code=404,
|
||||
)
|
||||
|
||||
file = files[0]
|
||||
file_contents = SpecFileService.get_data(process_model, file.name)
|
||||
file.file_contents = file_contents
|
||||
file.process_model_id = process_model.id
|
||||
# file.process_group_id = process_model.process_group_id
|
||||
return FileSchema().dump(file)
|
Loading…
Reference in New Issue