actually create process model

This commit is contained in:
burnettk 2022-12-30 19:51:17 -05:00
parent afd6bcbc35
commit 2adb6b206e
2 changed files with 112 additions and 59 deletions

View File

@ -16,6 +16,7 @@ from flask.wrappers import Response
from flask_bpmn.api.api_error import ApiError from flask_bpmn.api.api_error import ApiError
from spiffworkflow_backend.models.file import FileSchema from spiffworkflow_backend.models.file import FileSchema
from spiffworkflow_backend.models.process_group import ProcessGroup
from spiffworkflow_backend.models.process_model import ProcessModelInfo from spiffworkflow_backend.models.process_model import ProcessModelInfo
from spiffworkflow_backend.models.process_model import ProcessModelInfoSchema from spiffworkflow_backend.models.process_model import ProcessModelInfoSchema
from spiffworkflow_backend.routes.process_api_blueprint import _commit_and_push_to_git from spiffworkflow_backend.routes.process_api_blueprint import _commit_and_push_to_git
@ -47,23 +48,7 @@ def process_model_create(
if include_item in body if include_item in body
} }
if modified_process_group_id is None: _get_process_group_from_modified_identifier(modified_process_group_id)
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 process_model_info = ProcessModelInfo(**body_filtered) # type: ignore
if process_model_info is None: if process_model_info is None:
@ -151,7 +136,8 @@ def process_model_move(
original_process_model_id, new_location original_process_model_id, new_location
) )
_commit_and_push_to_git( _commit_and_push_to_git(
f"User: {g.user.username} moved process model {original_process_model_id} to {new_process_model.id}" f"User: {g.user.username} moved process model {original_process_model_id} to"
f" {new_process_model.id}"
) )
return make_response(jsonify(new_process_model), 200) return make_response(jsonify(new_process_model), 200)
@ -224,7 +210,8 @@ def process_model_file_update(
SpecFileService.update_file(process_model, file_name, request_file_contents) SpecFileService.update_file(process_model, file_name, request_file_contents)
_commit_and_push_to_git( _commit_and_push_to_git(
f"User: {g.user.username} clicked save for {process_model_identifier}/{file_name}" f"User: {g.user.username} clicked save for"
f" {process_model_identifier}/{file_name}"
) )
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json") return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
@ -248,7 +235,8 @@ def process_model_file_delete(
) from exception ) from exception
_commit_and_push_to_git( _commit_and_push_to_git(
f"User: {g.user.username} deleted process model file {process_model_identifier}/{file_name}" f"User: {g.user.username} deleted process model file"
f" {process_model_identifier}/{file_name}"
) )
return Response(json.dumps({"ok": True}), status=200, mimetype="application/json") return Response(json.dumps({"ok": True}), status=200, mimetype="application/json")
@ -274,7 +262,8 @@ def process_model_file_create(
file.file_contents = file_contents file.file_contents = file_contents
file.process_model_id = process_model.id file.process_model_id = process_model.id
_commit_and_push_to_git( _commit_and_push_to_git(
f"User: {g.user.username} added process model file {process_model_identifier}/{file.name}" f"User: {g.user.username} added process model file"
f" {process_model_identifier}/{file.name}"
) )
return Response( return Response(
json.dumps(FileSchema().dump(file)), status=201, mimetype="application/json" json.dumps(FileSchema().dump(file)), status=201, mimetype="application/json"
@ -291,8 +280,10 @@ def process_model_file_show(
if len(files) == 0: if len(files) == 0:
raise ApiError( raise ApiError(
error_code="unknown file", error_code="unknown file",
message=f"No information exists for file {file_name}" message=(
f" it does not exist in workflow {process_model_identifier}.", f"No information exists for file {file_name}"
f" it does not exist in workflow {process_model_identifier}."
),
status_code=404, status_code=404,
) )
@ -303,12 +294,14 @@ def process_model_file_show(
return FileSchema().dump(file) return FileSchema().dump(file)
# { # {
# "natural_language_text": "Create a bug tracker process model with a bug-details form that collects summary, description, and priority" # "natural_language_text": "Create a bug tracker process model \
# } # with a bug-details form that collects summary, description, and priority"
# }
def process_model_create_with_natural_language( def process_model_create_with_natural_language(
modified_process_group_id: str, body: Dict[str, Union[str, bool, int]] modified_process_group_id: str, body: Dict[str, str]
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
"""Process_model_create_with_natural_language."""
# body_include_list = [ # body_include_list = [
# "id", # "id",
# "display_name", # "display_name",
@ -323,41 +316,66 @@ def process_model_create_with_natural_language(
# if include_item in body # if include_item in body
# } # }
pattern = re.compile(r"Create a (?P<pm_name>.*?) process model with a (?P<form_name>.*?) form that collects (?P<columns_hey>.*)") pattern = re.compile(
r"Create a (?P<pm_name>.*?) process model with a (?P<form_name>.*?) form that"
r" collects (?P<columns>.*)"
)
match = pattern.match(body["natural_language_text"]) match = pattern.match(body["natural_language_text"])
process_model_display_name = match.group('pm_name') if match is None:
process_model_identifier = re.sub(r"[ _]", '-', process_model_display_name) raise ApiError(
process_model_identifier = re.sub(r"-{2,}", '-', process_model_identifier).lower() error_code="natural_language_text_not_yet_supported",
message=(
"Natural language text is not yet supported. Please use the form:"
f" {pattern.pattern}"
),
status_code=400,
)
process_model_display_name = match.group("pm_name")
process_model_identifier = re.sub(r"[ _]", "-", process_model_display_name)
process_model_identifier = re.sub(r"-{2,}", "-", process_model_identifier).lower()
print(f"process_model_identifier: {process_model_identifier}") print(f"process_model_identifier: {process_model_identifier}")
form_name = match.group('form_name') form_name = match.group("form_name")
form_identifier = re.sub(r"[ _]", '-', form_name) form_identifier = re.sub(r"[ _]", "-", form_name)
form_identifier = re.sub(r"-{2,}", '-', form_identifier).lower() form_identifier = re.sub(r"-{2,}", "-", form_identifier).lower()
print(f"form_identifier: {form_identifier}") print(f"form_identifier: {form_identifier}")
column_names = match.group('columns_hey') column_names = match.group("columns")
print(f"column_names: {column_names}") print(f"column_names: {column_names}")
columns = re.sub(r"(, (and )?)", ',', column_names).split(',') columns = re.sub(r"(, (and )?)", ",", column_names).split(",")
print(f"columns: {columns}") print(f"columns: {columns}")
#
# 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_group = _get_process_group_from_modified_identifier(
modified_process_group_id
)
qualified_process_model_identifier = (
f"{process_group.id}/{process_model_identifier}"
)
process_model_attributes = {
"id": qualified_process_model_identifier,
"display_name": process_model_display_name,
"description": None,
}
process_model_info = ProcessModelInfo(**process_model_attributes) # 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 via natural language:"
f" {process_model_info.id}"
)
return Response(
json.dumps(ProcessModelInfoSchema().dump(process_model_info)),
status=201,
mimetype="application/json",
)
def _get_file_from_request() -> Any: def _get_file_from_request() -> Any:
@ -370,3 +388,33 @@ def _get_file_from_request() -> Any:
status_code=400, status_code=400,
) )
return request_file return request_file
def _get_process_group_from_modified_identifier(
modified_process_group_id: str,
) -> ProcessGroup:
"""_get_process_group_from_modified_identifier."""
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=(
"Process Model could not be created from given body because Process"
f" Group could not be found: {unmodified_process_group_id}"
),
status_code=400,
)
return process_group

View File

@ -170,6 +170,7 @@ class TestProcessApi(BaseTest):
with_db_and_bpmn_file_cleanup: None, with_db_and_bpmn_file_cleanup: None,
with_super_admin_user: UserModel, with_super_admin_user: UserModel,
) -> None: ) -> None:
"""Test_process_model_create_with_natural_language."""
process_group_id = "test_process_group" process_group_id = "test_process_group"
process_group_description = "Test Process Group" process_group_description = "Test Process Group"
process_model_id = "sample" process_model_id = "sample"
@ -178,9 +179,11 @@ class TestProcessApi(BaseTest):
client, with_super_admin_user, process_group_id, process_group_description client, with_super_admin_user, process_group_id, process_group_description
) )
body = { text = "Create a Bug Tracker process model "
"natural_language_text": "Create a Bug Tracker process model with a Bug Details form that collects summary, description, and priority" text += (
} "with a Bug Details form that collects summary, description, and priority"
)
body = {"natural_language_text": text}
self.create_process_model_with_api( self.create_process_model_with_api(
client, client,
process_model_id=process_model_identifier, process_model_id=process_model_identifier,
@ -193,6 +196,9 @@ class TestProcessApi(BaseTest):
headers=self.logged_in_headers(with_super_admin_user), headers=self.logged_in_headers(with_super_admin_user),
) )
assert response.status_code == 201 assert response.status_code == 201
assert response.json is not None
assert response.json["id"] == f"{process_group_id}/bug-tracker"
assert response.json["display_name"] == "Bug Tracker"
def test_primary_process_id_updates_via_xml( def test_primary_process_id_updates_via_xml(
self, self,
@ -281,7 +287,6 @@ class TestProcessApi(BaseTest):
assert response.json is not None assert response.json is not None
assert response.json["ok"] is True assert response.json["ok"] is True
def test_process_model_delete_with_instances( def test_process_model_delete_with_instances(
self, self,
app: Flask, app: Flask,