Removing dependency on flask-bpmn and taking it out of SpiffArena
Slightly updating the APIError code for recent updates to SpiffWorkflow's error refactoring.
This commit is contained in:
parent
994620bc5f
commit
28a28e353b
|
@ -1,7 +1,7 @@
|
|||
"""Grabs tickets from csv and makes process instances."""
|
||||
import csv
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.models.db import db
|
||||
|
||||
from spiffworkflow_backend import get_hacked_up_app_for_script
|
||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
||||
|
|
|
@ -5,7 +5,7 @@ def main():
|
|||
"""Use main to avoid global namespace."""
|
||||
import csv
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.models.db import db
|
||||
|
||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
||||
from spiffworkflow_backend.models.user import UserModel
|
||||
|
|
|
@ -5,8 +5,9 @@ import shutil
|
|||
import pytest
|
||||
from flask.app import Flask
|
||||
from flask.testing import FlaskClient
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||
|
||||
from spiffworkflow_backend.models.human_task_user import HumanTaskUserModel
|
||||
|
|
|
@ -610,37 +610,6 @@ python-versions = "*"
|
|||
bcrypt = ">=3.1.1"
|
||||
Flask = "*"
|
||||
|
||||
[[package]]
|
||||
name = "flask-bpmn"
|
||||
version = "0.0.0"
|
||||
description = "Flask Bpmn"
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "^3.7"
|
||||
develop = false
|
||||
|
||||
[package.dependencies]
|
||||
click = "^8.0.1"
|
||||
flask = "*"
|
||||
flask-admin = "*"
|
||||
flask-bcrypt = "*"
|
||||
flask-cors = "*"
|
||||
flask-mail = "*"
|
||||
flask-marshmallow = "*"
|
||||
flask-migrate = "*"
|
||||
flask-restful = "*"
|
||||
greenlet = "^2.0.1"
|
||||
sentry-sdk = "*"
|
||||
sphinx-autoapi = "^2.0.0"
|
||||
spiffworkflow = "*"
|
||||
werkzeug = "*"
|
||||
|
||||
[package.source]
|
||||
type = "git"
|
||||
url = "https://github.com/sartography/flask-bpmn"
|
||||
reference = "main"
|
||||
resolved_reference = "c18306300f4312b8d36e0197fd6b62399180d0b1"
|
||||
|
||||
[[package]]
|
||||
name = "Flask-Cors"
|
||||
version = "3.0.10"
|
||||
|
@ -1776,7 +1745,7 @@ description = "A workflow framework and BPMN/DMN Processor"
|
|||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
develop = false
|
||||
develop = true
|
||||
|
||||
[package.dependencies]
|
||||
celery = "*"
|
||||
|
@ -1784,10 +1753,8 @@ configparser = "*"
|
|||
lxml = "*"
|
||||
|
||||
[package.source]
|
||||
type = "git"
|
||||
url = "https://github.com/sartography/SpiffWorkflow"
|
||||
reference = "main"
|
||||
resolved_reference = "be26100bcbef8026e26312c665dae42faf476485"
|
||||
type = "directory"
|
||||
url = "../../SpiffWorkflow"
|
||||
|
||||
[[package]]
|
||||
name = "SQLAlchemy"
|
||||
|
@ -2158,7 +2125,7 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools"
|
|||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = ">=3.9,<3.12"
|
||||
content-hash = "8592e94ba80b7d0338a9c003ca4d0e189b5f470d97391438ddc1fc9050febedb"
|
||||
content-hash = "f646836512a18f2a0e9ba4979926e004abd17790da5178e06e87092fdf23c35f"
|
||||
|
||||
[metadata.files]
|
||||
alabaster = [
|
||||
|
@ -2421,7 +2388,6 @@ Flask-Bcrypt = [
|
|||
{file = "Flask-Bcrypt-1.0.1.tar.gz", hash = "sha256:f07b66b811417ea64eb188ae6455b0b708a793d966e1a80ceec4a23bc42a4369"},
|
||||
{file = "Flask_Bcrypt-1.0.1-py3-none-any.whl", hash = "sha256:062fd991dc9118d05ac0583675507b9fe4670e44416c97e0e6819d03d01f808a"},
|
||||
]
|
||||
flask-bpmn = []
|
||||
Flask-Cors = [
|
||||
{file = "Flask-Cors-3.0.10.tar.gz", hash = "sha256:b60839393f3b84a0f3746f6cdca56c1ad7426aa738b70d6c61375857823181de"},
|
||||
{file = "Flask_Cors-3.0.10-py2.py3-none-any.whl", hash = "sha256:74efc975af1194fc7891ff5cd85b0f7478be4f7f59fe158102e91abb72bb4438"},
|
||||
|
@ -2499,6 +2465,7 @@ greenlet = [
|
|||
{file = "greenlet-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5b0ff9878333823226d270417f24f4d06f235cb3e54d1103b71ea537a6a86ce"},
|
||||
{file = "greenlet-2.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be9e0fb2ada7e5124f5282d6381903183ecc73ea019568d6d63d33f25b2a9000"},
|
||||
{file = "greenlet-2.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b493db84d124805865adc587532ebad30efa68f79ad68f11b336e0a51ec86c2"},
|
||||
{file = "greenlet-2.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0459d94f73265744fee4c2d5ec44c6f34aa8a31017e6e9de770f7bcf29710be9"},
|
||||
{file = "greenlet-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a20d33124935d27b80e6fdacbd34205732660e0a1d35d8b10b3328179a2b51a1"},
|
||||
{file = "greenlet-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:ea688d11707d30e212e0110a1aac7f7f3f542a259235d396f88be68b649e47d1"},
|
||||
{file = "greenlet-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:afe07421c969e259e9403c3bb658968702bc3b78ec0b6fde3ae1e73440529c23"},
|
||||
|
@ -2507,6 +2474,7 @@ greenlet = [
|
|||
{file = "greenlet-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:659f167f419a4609bc0516fb18ea69ed39dbb25594934bd2dd4d0401660e8a1e"},
|
||||
{file = "greenlet-2.0.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:356e4519d4dfa766d50ecc498544b44c0249b6de66426041d7f8b751de4d6b48"},
|
||||
{file = "greenlet-2.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:811e1d37d60b47cb8126e0a929b58c046251f28117cb16fcd371eed61f66b764"},
|
||||
{file = "greenlet-2.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d38ffd0e81ba8ef347d2be0772e899c289b59ff150ebbbbe05dc61b1246eb4e0"},
|
||||
{file = "greenlet-2.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0109af1138afbfb8ae647e31a2b1ab030f58b21dd8528c27beaeb0093b7938a9"},
|
||||
{file = "greenlet-2.0.1-cp38-cp38-win32.whl", hash = "sha256:88c8d517e78acdf7df8a2134a3c4b964415b575d2840a2746ddb1cc6175f8608"},
|
||||
{file = "greenlet-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:d6ee1aa7ab36475035eb48c01efae87d37936a8173fc4d7b10bb02c2d75dd8f6"},
|
||||
|
@ -2515,6 +2483,7 @@ greenlet = [
|
|||
{file = "greenlet-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:505138d4fa69462447a562a7c2ef723c6025ba12ac04478bc1ce2fcc279a2db5"},
|
||||
{file = "greenlet-2.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cce1e90dd302f45716a7715517c6aa0468af0bf38e814ad4eab58e88fc09f7f7"},
|
||||
{file = "greenlet-2.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e9744c657d896c7b580455e739899e492a4a452e2dd4d2b3e459f6b244a638d"},
|
||||
{file = "greenlet-2.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:662e8f7cad915ba75d8017b3e601afc01ef20deeeabf281bd00369de196d7726"},
|
||||
{file = "greenlet-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:41b825d65f31e394b523c84db84f9383a2f7eefc13d987f308f4663794d2687e"},
|
||||
{file = "greenlet-2.0.1-cp39-cp39-win32.whl", hash = "sha256:db38f80540083ea33bdab614a9d28bcec4b54daa5aff1668d7827a9fc769ae0a"},
|
||||
{file = "greenlet-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:b23d2a46d53210b498e5b701a1913697671988f4bf8e10f935433f6e7c332fb6"},
|
||||
|
@ -2813,10 +2782,7 @@ orjson = [
|
|||
{file = "orjson-3.8.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b68a42a31f8429728183c21fb440c21de1b62e5378d0d73f280e2d894ef8942e"},
|
||||
{file = "orjson-3.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ff13410ddbdda5d4197a4a4c09969cb78c722a67550f0a63c02c07aadc624833"},
|
||||
{file = "orjson-3.8.0-cp310-none-win_amd64.whl", hash = "sha256:2d81e6e56bbea44be0222fb53f7b255b4e7426290516771592738ca01dbd053b"},
|
||||
{file = "orjson-3.8.0-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:200eae21c33f1f8b02a11f5d88d76950cd6fd986d88f1afe497a8ae2627c49aa"},
|
||||
{file = "orjson-3.8.0-cp311-cp311-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:9529990f3eab54b976d327360aa1ff244a4b12cb5e4c5b3712fcdd96e8fe56d4"},
|
||||
{file = "orjson-3.8.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:e2defd9527651ad39ec20ae03c812adf47ef7662bdd6bc07dabb10888d70dc62"},
|
||||
{file = "orjson-3.8.0-cp311-none-win_amd64.whl", hash = "sha256:b21c7af0ff6228ca7105f54f0800636eb49201133e15ddb80ac20c1ce973ef07"},
|
||||
{file = "orjson-3.8.0-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:9e6ac22cec72d5b39035b566e4b86c74b84866f12b5b0b6541506a080fb67d6d"},
|
||||
{file = "orjson-3.8.0-cp37-cp37m-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:e2f4a5542f50e3d336a18cb224fc757245ca66b1fd0b70b5dd4471b8ff5f2b0e"},
|
||||
{file = "orjson-3.8.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1418feeb8b698b9224b1f024555895169d481604d5d884498c1838d7412794c"},
|
||||
|
|
|
@ -27,12 +27,10 @@ flask-marshmallow = "*"
|
|||
flask-migrate = "*"
|
||||
flask-restful = "*"
|
||||
werkzeug = "*"
|
||||
SpiffWorkflow = {git = "https://github.com/sartography/SpiffWorkflow", rev = "main"}
|
||||
#SpiffWorkflow = {develop = true, path = "../SpiffWorkflow" }
|
||||
#SpiffWorkflow = {git = "https://github.com/sartography/SpiffWorkflow", rev = "main"}
|
||||
SpiffWorkflow = {develop = true, path = "/home/dan/code/workflow/SpiffWorkflow" }
|
||||
sentry-sdk = "^1.10"
|
||||
sphinx-autoapi = "^2.0"
|
||||
flask-bpmn = {git = "https://github.com/sartography/flask-bpmn", rev = "main"}
|
||||
# flask-bpmn = {develop = true, path = "../flask-bpmn"}
|
||||
mysql-connector-python = "*"
|
||||
pytest-flask = "^1.2.0"
|
||||
pytest-flask-sqlalchemy = "^1.1.0"
|
||||
|
|
|
@ -9,9 +9,9 @@ import sqlalchemy
|
|||
from apscheduler.schedulers.background import BackgroundScheduler # type: ignore
|
||||
from apscheduler.schedulers.base import BaseScheduler # type: ignore
|
||||
from flask.json.provider import DefaultJSONProvider
|
||||
from flask_bpmn.api.api_error import api_error_blueprint
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import migrate
|
||||
from spiffworkflow_backend.exceptions.api_error import api_error_blueprint
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import migrate
|
||||
from flask_cors import CORS # type: ignore
|
||||
from flask_mail import Mail # type: ignore
|
||||
from werkzeug.exceptions import NotFound
|
||||
|
|
|
@ -16,12 +16,19 @@ users:
|
|||
email: malala@spiffworkflow.org
|
||||
password: malala
|
||||
preferred_username: Malala
|
||||
oskar:
|
||||
service: local_open_id
|
||||
email: oskar@spiffworkflow.org
|
||||
password: oskar
|
||||
preferred_username: Oskar
|
||||
|
||||
|
||||
groups:
|
||||
admin:
|
||||
users:
|
||||
[
|
||||
admin@spiffworkflow.org,
|
||||
oskar@spiffworkflow.org
|
||||
]
|
||||
Education:
|
||||
users:
|
||||
|
@ -88,3 +95,11 @@ permissions:
|
|||
users: []
|
||||
allowed_permissions: [create, read]
|
||||
uri: /process-instances/misc:category_number_one:process-model-with-form/*
|
||||
|
||||
# Anyone can see their own user groups.
|
||||
groups-everybody:
|
||||
groups: [everybody]
|
||||
users: []
|
||||
allowed_permissions: [create, read]
|
||||
uri: /v1.0/user-groups/for-current-user
|
||||
|
||||
|
|
|
@ -0,0 +1,206 @@
|
|||
"""API Error functionality."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from dataclasses import dataclass
|
||||
from dataclasses import field
|
||||
from typing import Any
|
||||
|
||||
import flask.wrappers
|
||||
import sentry_sdk
|
||||
from flask import Blueprint
|
||||
from flask import current_app
|
||||
from flask import g
|
||||
from flask import jsonify
|
||||
from flask import make_response
|
||||
from sentry_sdk import capture_exception
|
||||
from sentry_sdk import set_tag
|
||||
from SpiffWorkflow.exceptions import WorkflowException, WorkflowTaskException # type: ignore
|
||||
from SpiffWorkflow.specs.base import TaskSpec # type: ignore
|
||||
from SpiffWorkflow.task import Task # type: ignore
|
||||
|
||||
|
||||
api_error_blueprint = Blueprint("api_error_blueprint", __name__)
|
||||
|
||||
|
||||
@dataclass
|
||||
class ApiError(Exception):
|
||||
"""ApiError Class to help handle exceptions."""
|
||||
|
||||
error_code: str
|
||||
message: str
|
||||
error_line: str = ""
|
||||
error_type: str = ""
|
||||
file_name: str = ""
|
||||
line_number: int = 0
|
||||
offset: int = 0
|
||||
sentry_link: str | None = None
|
||||
status_code: int = 400
|
||||
tag: str = ""
|
||||
task_data: dict | str | None = field(default_factory=dict)
|
||||
task_id: str = ""
|
||||
task_name: str = ""
|
||||
task_trace: dict | None = field(default_factory=dict)
|
||||
|
||||
def __str__(self) -> str:
|
||||
"""Instructions to print instance as a string."""
|
||||
msg = "ApiError: % s. " % self.message
|
||||
if self.task_name:
|
||||
msg += f"Error in task '{self.task_name}' ({self.task_id}). "
|
||||
if self.line_number:
|
||||
msg += "Error is on line %i. " % self.line_number
|
||||
if self.file_name:
|
||||
msg += "In file %s. " % self.file_name
|
||||
return msg
|
||||
|
||||
@classmethod
|
||||
def from_task(
|
||||
cls,
|
||||
error_code: str,
|
||||
message: str,
|
||||
task: Task,
|
||||
status_code: int = 400,
|
||||
line_number: int = 0,
|
||||
offset: int = 0,
|
||||
error_type: str = "",
|
||||
error_line: str = "",
|
||||
task_trace: dict | None = None,
|
||||
) -> ApiError:
|
||||
"""Constructs an API Error with details pulled from the current task."""
|
||||
instance = cls(error_code, message, status_code=status_code)
|
||||
instance.task_id = task.task_spec.name or ""
|
||||
instance.task_name = task.task_spec.description or ""
|
||||
instance.file_name = task.workflow.spec.file or ""
|
||||
instance.line_number = line_number
|
||||
instance.offset = offset
|
||||
instance.error_type = error_type
|
||||
instance.error_line = error_line
|
||||
if task_trace:
|
||||
instance.task_trace = task_trace
|
||||
else:
|
||||
instance.task_trace = WorkflowTaskException.get_task_trace(task)
|
||||
|
||||
# spiffworkflow is doing something weird where task ends up referenced in the data in some cases.
|
||||
if "task" in task.data:
|
||||
task.data.pop("task")
|
||||
|
||||
# Assure that there is nothing in the json data that can't be serialized.
|
||||
instance.task_data = ApiError.remove_unserializeable_from_dict(task.data)
|
||||
|
||||
return instance
|
||||
|
||||
@staticmethod
|
||||
def remove_unserializeable_from_dict(my_dict: dict) -> dict:
|
||||
"""Removes unserializeable from dict."""
|
||||
keys_to_delete = []
|
||||
for key, value in my_dict.items():
|
||||
if not ApiError.is_jsonable(value):
|
||||
keys_to_delete.append(key)
|
||||
for key in keys_to_delete:
|
||||
del my_dict[key]
|
||||
return my_dict
|
||||
|
||||
@staticmethod
|
||||
def is_jsonable(x: Any) -> bool:
|
||||
"""Attempts a json.dump on given input and returns false if it cannot."""
|
||||
try:
|
||||
json.dumps(x)
|
||||
return True
|
||||
except (TypeError, OverflowError, ValueError):
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def from_task_spec(
|
||||
cls,
|
||||
code: str,
|
||||
message: str,
|
||||
task_spec: TaskSpec,
|
||||
status_code: int = 400,
|
||||
) -> ApiError:
|
||||
"""Constructs an API Error with details pulled from the current task."""
|
||||
instance = cls(code, message, status_code=status_code)
|
||||
instance.task_id = task_spec.name or ""
|
||||
instance.task_name = task_spec.description or ""
|
||||
if task_spec._wf_spec:
|
||||
instance.file_name = task_spec._wf_spec.file
|
||||
return instance
|
||||
|
||||
@classmethod
|
||||
def from_workflow_exception(
|
||||
cls,
|
||||
error_code: str,
|
||||
message: str,
|
||||
exp: WorkflowException,
|
||||
) -> ApiError:
|
||||
"""Deals with workflow exceptions.
|
||||
|
||||
We catch a lot of workflow exception errors,
|
||||
so consolidating the error_code, and doing the best things
|
||||
we can with the data we have.
|
||||
"""
|
||||
if isinstance(exp, WorkflowTaskException):
|
||||
return ApiError.from_task(
|
||||
error_code,
|
||||
message,
|
||||
exp.task,
|
||||
line_number=exp.line_number,
|
||||
offset=exp.offset,
|
||||
error_type=exp.error_type,
|
||||
error_line=exp.error_line,
|
||||
task_trace=exp.task_trace,
|
||||
)
|
||||
|
||||
else:
|
||||
return ApiError.from_task_spec(error_code, message, exp.sender)
|
||||
|
||||
|
||||
def set_user_sentry_context() -> None:
|
||||
"""Set_user_sentry_context."""
|
||||
try:
|
||||
username = g.user.username
|
||||
except Exception:
|
||||
username = "Unknown"
|
||||
# This is for sentry logging into Slack
|
||||
sentry_sdk.set_context("User", {"user": username})
|
||||
set_tag("username", username)
|
||||
|
||||
|
||||
@api_error_blueprint.app_errorhandler(Exception)
|
||||
def handle_exception(exception: Exception) -> flask.wrappers.Response:
|
||||
"""Handles unexpected exceptions."""
|
||||
set_user_sentry_context()
|
||||
|
||||
sentry_link = None
|
||||
if not isinstance(exception, ApiError) or exception.error_code != "invalid_token":
|
||||
id = capture_exception(exception)
|
||||
|
||||
if isinstance(exception, ApiError):
|
||||
current_app.logger.info(
|
||||
f"Sending ApiError exception to sentry: {exception} with error code {exception.error_code}")
|
||||
|
||||
organization_slug = current_app.config.get("SENTRY_ORGANIZATION_SLUG")
|
||||
project_slug = current_app.config.get("SENTRY_PROJECT_SLUG")
|
||||
if organization_slug and project_slug:
|
||||
sentry_link = (
|
||||
f"https://sentry.io/{organization_slug}/{project_slug}/events/{id}"
|
||||
)
|
||||
|
||||
# !!!NOTE!!!: do this after sentry stuff since calling logger.exception
|
||||
# seems to break the sentry sdk context where we no longer get back
|
||||
# an event id or send out tags like username
|
||||
current_app.logger.exception(exception)
|
||||
|
||||
# set api_exception like this to avoid confusing mypy
|
||||
# and what type the object is
|
||||
api_exception = None
|
||||
if isinstance(exception, ApiError):
|
||||
api_exception = exception
|
||||
else:
|
||||
api_exception = ApiError(
|
||||
error_code="internal_server_error",
|
||||
message=f"{exception.__class__.__name__}",
|
||||
sentry_link=sentry_link,
|
||||
status_code=500,
|
||||
)
|
||||
|
||||
return make_response(jsonify(api_exception), api_exception.status_code)
|
|
@ -2,7 +2,7 @@
|
|||
import time
|
||||
|
||||
import sqlalchemy
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.models.db import db
|
||||
|
||||
|
||||
def try_to_connect(start_time: float) -> None:
|
||||
|
|
|
@ -8,7 +8,7 @@ avoid circular imports
|
|||
"""
|
||||
|
||||
|
||||
from flask_bpmn.models.db import add_listeners
|
||||
from spiffworkflow_backend.models.db import add_listeners
|
||||
|
||||
# must load these before UserModel and GroupModel for relationships
|
||||
from spiffworkflow_backend.models.user_group_assignment import (
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
"""Db."""
|
||||
from __future__ import annotations
|
||||
|
||||
import enum
|
||||
import time
|
||||
from typing import Any
|
||||
|
||||
from flask_migrate import Migrate # type: ignore
|
||||
from flask_sqlalchemy import SQLAlchemy # type: ignore
|
||||
from sqlalchemy import event # type: ignore
|
||||
from sqlalchemy.engine.base import Connection # type: ignore
|
||||
from sqlalchemy.orm.mapper import Mapper # type: ignore
|
||||
|
||||
db = SQLAlchemy()
|
||||
migrate = Migrate()
|
||||
|
||||
|
||||
class SpiffworkflowBaseDBModel(db.Model): # type: ignore
|
||||
"""SpiffworkflowBaseDBModel."""
|
||||
|
||||
__abstract__ = True
|
||||
|
||||
@classmethod
|
||||
def _all_subclasses(cls) -> list[type[SpiffworkflowBaseDBModel]]:
|
||||
"""Get all subclasses of cls, descending.
|
||||
|
||||
So, if A is a subclass of B is a subclass of cls, this
|
||||
will include A and B.
|
||||
(Does not include cls)
|
||||
"""
|
||||
children = cls.__subclasses__()
|
||||
result = []
|
||||
while children:
|
||||
next = children.pop()
|
||||
subclasses = next.__subclasses__()
|
||||
result.append(next)
|
||||
# check subclasses of subclasses SpiffworkflowBaseDBModel. i guess we only go down to grandchildren, which seems cool.
|
||||
for subclass in subclasses:
|
||||
children.append(subclass)
|
||||
return result
|
||||
|
||||
def validate_enum_field(
|
||||
self, key: str, value: Any, enum_variable: enum.EnumMeta
|
||||
) -> Any:
|
||||
"""Validate_enum_field."""
|
||||
try:
|
||||
m_type = getattr(enum_variable, value, None)
|
||||
except Exception as e:
|
||||
raise ValueError(
|
||||
f"{self.__class__.__name__}: invalid {key}: {value}"
|
||||
) from e
|
||||
|
||||
if m_type is None:
|
||||
raise ValueError(f"{self.__class__.__name__}: invalid {key}: {value}")
|
||||
|
||||
return m_type.value
|
||||
|
||||
|
||||
def update_created_modified_on_create_listener(
|
||||
mapper: Mapper, _connection: Connection, target: SpiffworkflowBaseDBModel
|
||||
) -> None:
|
||||
"""Event listener that runs before a record is updated, and sets the create/modified field accordingly."""
|
||||
if "created_at_in_seconds" in mapper.columns.keys():
|
||||
target.created_at_in_seconds = round(time.time())
|
||||
if "updated_at_in_seconds" in mapper.columns.keys():
|
||||
target.updated_at_in_seconds = round(time.time())
|
||||
|
||||
|
||||
def update_modified_on_update_listener(
|
||||
mapper: Mapper, _connection: Connection, target: SpiffworkflowBaseDBModel
|
||||
) -> None:
|
||||
"""Event listener that runs before a record is updated, and sets the modified field accordingly."""
|
||||
if "updated_at_in_seconds" in mapper.columns.keys():
|
||||
if db.session.is_modified(target, include_collections=False):
|
||||
target.updated_at_in_seconds = round(time.time())
|
||||
|
||||
|
||||
def add_listeners() -> None:
|
||||
"""Adds the listeners to all subclasses.
|
||||
|
||||
This should be called after importing all subclasses
|
||||
"""
|
||||
for cls in SpiffworkflowBaseDBModel._all_subclasses():
|
||||
event.listen(cls, "before_insert", update_created_modified_on_create_listener)
|
||||
event.listen(cls, "before_update", update_modified_on_update_listener)
|
|
@ -3,8 +3,7 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.group import FlaskBpmnGroupModel
|
||||
from spiffworkflow_backend.models.db import db, SpiffworkflowBaseDBModel
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
@ -18,12 +17,14 @@ class GroupNotFoundError(Exception):
|
|||
"""GroupNotFoundError."""
|
||||
|
||||
|
||||
class GroupModel(FlaskBpmnGroupModel):
|
||||
class GroupModel(SpiffworkflowBaseDBModel):
|
||||
"""GroupModel."""
|
||||
|
||||
__tablename__ = "group"
|
||||
__table_args__ = {"extend_existing": True}
|
||||
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
name = db.Column(db.String(255))
|
||||
identifier = db.Column(db.String(255))
|
||||
|
||||
user_group_assignments = relationship("UserGroupAssignmentModel", cascade="delete")
|
||||
|
|
|
@ -4,8 +4,9 @@ from __future__ import annotations
|
|||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from sqlalchemy import ForeignKey
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
|
|
|
@ -3,8 +3,9 @@ from __future__ import annotations
|
|||
|
||||
from dataclasses import dataclass
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from sqlalchemy import ForeignKey
|
||||
|
||||
from spiffworkflow_backend.models.human_task import HumanTaskModel
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
from dataclasses import dataclass
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from sqlalchemy import ForeignKey
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
"""Message_correlation_message_instance."""
|
||||
from dataclasses import dataclass
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from sqlalchemy import ForeignKey
|
||||
|
||||
from spiffworkflow_backend.models.message_correlation import MessageCorrelationModel
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""Message_correlation_property."""
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from sqlalchemy import ForeignKey
|
||||
|
||||
from spiffworkflow_backend.models.message_model import MessageModel
|
||||
|
|
|
@ -5,8 +5,9 @@ from typing import Any
|
|||
from typing import Optional
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from sqlalchemy import ForeignKey
|
||||
from sqlalchemy.event import listens_for
|
||||
from sqlalchemy.orm import relationship
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""Message_model."""
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
|
||||
|
||||
class MessageModel(SpiffworkflowBaseDBModel):
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""Message_correlation_property."""
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from sqlalchemy import ForeignKey
|
||||
|
||||
from spiffworkflow_backend.models.message_model import MessageModel
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
import enum
|
||||
from typing import Any
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from sqlalchemy import ForeignKey
|
||||
from sqlalchemy.orm import validates
|
||||
|
||||
|
|
|
@ -3,8 +3,9 @@ import re
|
|||
from dataclasses import dataclass
|
||||
from typing import Optional
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from sqlalchemy.orm import validates
|
||||
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
"""Principal."""
|
||||
from dataclasses import dataclass
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from sqlalchemy import ForeignKey
|
||||
from sqlalchemy.orm import relationship
|
||||
from sqlalchemy.schema import CheckConstraint
|
||||
|
|
|
@ -5,8 +5,9 @@ from typing import Any
|
|||
from typing import cast
|
||||
|
||||
import marshmallow
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from marshmallow import INCLUDE
|
||||
from marshmallow import Schema
|
||||
from marshmallow_enum import EnumField # type: ignore
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
"""Process_instance_metadata."""
|
||||
from dataclasses import dataclass
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from sqlalchemy import ForeignKey
|
||||
|
||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
||||
|
|
|
@ -7,8 +7,9 @@ from typing import cast
|
|||
from typing import Optional
|
||||
from typing import TypedDict
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from sqlalchemy import ForeignKey
|
||||
from sqlalchemy.orm import deferred
|
||||
from sqlalchemy.orm import relationship
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
"""Refresh_token."""
|
||||
from dataclasses import dataclass
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from sqlalchemy import ForeignKey
|
||||
|
||||
# from sqlalchemy.orm import relationship
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
"""Secret_model."""
|
||||
from dataclasses import dataclass
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from marshmallow import Schema
|
||||
from sqlalchemy import ForeignKey
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
"""Message_model."""
|
||||
from dataclasses import dataclass
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from flask_marshmallow import Schema # type: ignore
|
||||
from marshmallow import INCLUDE
|
||||
from sqlalchemy import UniqueConstraint
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
from dataclasses import dataclass
|
||||
from typing import Optional
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
|
||||
|
||||
@dataclass
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
"""Spiff_step_details."""
|
||||
from dataclasses import dataclass
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from sqlalchemy import ForeignKey
|
||||
from sqlalchemy.orm import deferred
|
||||
|
||||
|
|
|
@ -6,8 +6,9 @@ from dataclasses import dataclass
|
|||
import jwt
|
||||
import marshmallow
|
||||
from flask import current_app
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from marshmallow import Schema
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""UserGroupAssignment."""
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from sqlalchemy import ForeignKey
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""UserGroupAssignment."""
|
||||
from flask_bpmn.models.db import db
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from sqlalchemy import ForeignKey
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ 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.api_error import ApiError
|
||||
|
||||
from spiffworkflow_backend.models.message_correlation import MessageCorrelationModel
|
||||
from spiffworkflow_backend.models.message_instance import MessageInstanceModel
|
||||
|
|
|
@ -11,8 +11,8 @@ 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_backend.exceptions.api_error import ApiError
|
||||
from spiffworkflow_backend.models.db import db
|
||||
|
||||
from spiffworkflow_backend.exceptions.process_entity_not_found_error import (
|
||||
ProcessEntityNotFoundError,
|
||||
|
|
|
@ -8,7 +8,7 @@ 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.api_error import ApiError
|
||||
|
||||
from spiffworkflow_backend.exceptions.process_entity_not_found_error import (
|
||||
ProcessEntityNotFoundError,
|
||||
|
|
|
@ -11,8 +11,8 @@ 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_backend.exceptions.api_error import ApiError
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from SpiffWorkflow.task import TaskState # type: ignore
|
||||
from sqlalchemy import and_
|
||||
from sqlalchemy import or_
|
||||
|
|
|
@ -14,7 +14,7 @@ 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.api_error import ApiError
|
||||
from werkzeug.datastructures import FileStorage
|
||||
|
||||
from spiffworkflow_backend.interfaces import IdToProcessGroupMapping
|
||||
|
@ -519,7 +519,7 @@ def _create_or_update_process_model_file(
|
|||
ApiError(
|
||||
error_code="process_model_file_invalid",
|
||||
message=(
|
||||
f"Invalid Process model file cannot be save: {request_file.name}."
|
||||
f"Invalid Process model file: {request_file.filename}."
|
||||
f" Received error: {str(exception)}"
|
||||
),
|
||||
status_code=400,
|
||||
|
|
|
@ -10,7 +10,7 @@ from flask import current_app
|
|||
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.api_error import ApiError
|
||||
from lxml import etree # type: ignore
|
||||
from lxml.builder import ElementMaker # type: ignore
|
||||
|
||||
|
|
|
@ -15,8 +15,8 @@ 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 flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from SpiffWorkflow.task import Task as SpiffTask # type: ignore
|
||||
from SpiffWorkflow.task import TaskState
|
||||
from sqlalchemy import and_
|
||||
|
|
|
@ -14,7 +14,7 @@ from flask import current_app
|
|||
from flask import g
|
||||
from flask import redirect
|
||||
from flask import request
|
||||
from flask_bpmn.api.api_error import ApiError
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
from werkzeug.wrappers import Response
|
||||
|
||||
from spiffworkflow_backend.models.user import UserModel
|
||||
|
|
|
@ -7,8 +7,8 @@ import flask.wrappers
|
|||
from flask import Blueprint
|
||||
from flask import request
|
||||
from flask import Response
|
||||
from flask_bpmn.api.api_error import ApiError
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
|
||||
from spiffworkflow_backend.models.group import GroupModel
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
from time import time
|
||||
from typing import Any
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from sqlalchemy import or_
|
||||
|
||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
||||
|
|
|
@ -3,7 +3,7 @@ from datetime import datetime
|
|||
from typing import Any
|
||||
|
||||
import pytz
|
||||
from flask_bpmn.api.api_error import ApiError
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
|
||||
from spiffworkflow_backend.models.script_attributes_context import (
|
||||
ScriptAttributesContext,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""Save process instance metadata."""
|
||||
from typing import Any
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.models.db import db
|
||||
|
||||
from spiffworkflow_backend.models.process_instance_metadata import (
|
||||
ProcessInstanceMetadataModel,
|
||||
|
|
|
@ -8,7 +8,7 @@ from abc import abstractmethod
|
|||
from typing import Any
|
||||
from typing import Callable
|
||||
|
||||
from flask_bpmn.api.api_error import ApiError
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
|
||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceNotFoundError
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import time
|
||||
|
||||
from flask import current_app
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||
|
||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
||||
|
|
|
@ -9,8 +9,8 @@ import jwt
|
|||
import requests
|
||||
from flask import current_app
|
||||
from flask import redirect
|
||||
from flask_bpmn.api.api_error import ApiError
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from werkzeug.wrappers import Response
|
||||
|
||||
from spiffworkflow_backend.models.refresh_token import RefreshTokenModel
|
||||
|
|
|
@ -17,8 +17,8 @@ from flask import current_app
|
|||
from flask import g
|
||||
from flask import request
|
||||
from flask import scaffold
|
||||
from flask_bpmn.api.api_error import ApiError
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from SpiffWorkflow.task import Task as SpiffTask # type: ignore
|
||||
from sqlalchemy import or_
|
||||
from sqlalchemy import text
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
"""Data_setup_service."""
|
||||
from flask import current_app
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.models.db import db
|
||||
|
||||
from spiffworkflow_backend.services.process_model_service import ProcessModelService
|
||||
from spiffworkflow_backend.services.spec_file_service import SpecFileService
|
||||
|
|
|
@ -5,8 +5,8 @@ from typing import Union
|
|||
from flask import current_app
|
||||
from flask import g
|
||||
from flask.wrappers import Response
|
||||
from flask_bpmn.api.api_error import ApiError
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
from spiffworkflow_backend.models.db import db
|
||||
|
||||
from spiffworkflow_backend.models.message_model import MessageModel
|
||||
from spiffworkflow_backend.models.message_triggerable_process_model import (
|
||||
|
|
|
@ -8,7 +8,7 @@ from typing import Optional
|
|||
|
||||
import pytz
|
||||
from flask import current_app
|
||||
from flask_bpmn.api.api_error import ApiError
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
|
||||
from spiffworkflow_backend.models.file import CONTENT_TYPES
|
||||
from spiffworkflow_backend.models.file import File
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""Group_service."""
|
||||
from typing import Optional
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.models.db import db
|
||||
|
||||
from spiffworkflow_backend.models.group import GroupModel
|
||||
from spiffworkflow_backend.models.user import UserModel
|
||||
|
|
|
@ -7,7 +7,7 @@ from typing import Optional
|
|||
|
||||
from flask import g
|
||||
from flask.app import Flask
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.models.db import db
|
||||
|
||||
from spiffworkflow_backend.models.spiff_logging import SpiffLoggingModel
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
from typing import Any
|
||||
from typing import Optional
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from sqlalchemy import and_
|
||||
from sqlalchemy import or_
|
||||
from sqlalchemy import select
|
||||
|
|
|
@ -22,11 +22,11 @@ from uuid import UUID
|
|||
import dateparser
|
||||
import pytz
|
||||
from flask import current_app
|
||||
from flask_bpmn.api.api_error import ApiError
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from lxml import etree # type: ignore
|
||||
from RestrictedPython import safe_globals # type: ignore
|
||||
from SpiffWorkflow.bpmn.exceptions import WorkflowTaskExecException # type: ignore
|
||||
from SpiffWorkflow.exceptions import WorkflowTaskException # type: ignore
|
||||
from SpiffWorkflow.bpmn.parser.ValidationException import ValidationException # type: ignore
|
||||
from SpiffWorkflow.bpmn.PythonScriptEngine import Box # type: ignore
|
||||
from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine
|
||||
|
@ -222,7 +222,7 @@ class CustomBpmnScriptEngine(PythonScriptEngine): # type: ignore
|
|||
% (expression, str(exception)),
|
||||
) from exception
|
||||
else:
|
||||
raise WorkflowTaskExecException(
|
||||
raise WorkflowTaskException(
|
||||
task,
|
||||
"Error evaluating expression '%s', %s"
|
||||
% (expression, str(exception)),
|
||||
|
@ -240,7 +240,7 @@ class CustomBpmnScriptEngine(PythonScriptEngine): # type: ignore
|
|||
except WorkflowException as e:
|
||||
raise e
|
||||
except Exception as e:
|
||||
raise WorkflowTaskExecException(task, f" {script}, {e}", e) from e
|
||||
raise WorkflowTaskException(task, f" {script}, {e}", e) from e
|
||||
|
||||
def call_service(
|
||||
self,
|
||||
|
@ -1284,7 +1284,7 @@ class ProcessInstanceProcessor:
|
|||
handler.bulk_insert_logs() # type: ignore
|
||||
db.session.commit()
|
||||
|
||||
except WorkflowTaskExecException as we:
|
||||
except WorkflowTaskException as we:
|
||||
raise ApiError.from_workflow_exception("task_error", str(we), we) from we
|
||||
|
||||
finally:
|
||||
|
@ -1304,7 +1304,7 @@ class ProcessInstanceProcessor:
|
|||
bpmn_process_instance.catch(CancelEventDefinition())
|
||||
# Due to this being static, can't save granular step details in this case
|
||||
bpmn_process_instance.do_engine_steps()
|
||||
except WorkflowTaskExecException as we:
|
||||
except WorkflowTaskException as we:
|
||||
raise ApiError.from_workflow_exception("task_error", str(we), we) from we
|
||||
|
||||
def user_defined_task_data(self, task_data: dict) -> dict:
|
||||
|
|
|
@ -6,8 +6,9 @@ from typing import Optional
|
|||
from typing import Type
|
||||
|
||||
import sqlalchemy
|
||||
from flask_bpmn.api.api_error import ApiError
|
||||
from flask_bpmn.models.db import SpiffworkflowBaseDBModel
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
|
||||
|
||||
from sqlalchemy import and_
|
||||
from sqlalchemy import func
|
||||
from sqlalchemy import or_
|
||||
|
|
|
@ -5,8 +5,8 @@ from typing import List
|
|||
from typing import Optional
|
||||
|
||||
from flask import current_app
|
||||
from flask_bpmn.api.api_error import ApiError
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from SpiffWorkflow.task import Task as SpiffTask # type: ignore
|
||||
|
||||
from spiffworkflow_backend.models.human_task import HumanTaskModel
|
||||
|
|
|
@ -8,7 +8,7 @@ from typing import List
|
|||
from typing import Optional
|
||||
from typing import TypeVar
|
||||
|
||||
from flask_bpmn.api.api_error import ApiError
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
|
||||
from spiffworkflow_backend.exceptions.process_entity_not_found_error import (
|
||||
ProcessEntityNotFoundError,
|
||||
|
|
|
@ -6,7 +6,7 @@ from dataclasses import dataclass
|
|||
from typing import Any
|
||||
from typing import Optional
|
||||
|
||||
from SpiffWorkflow.bpmn.exceptions import WorkflowTaskExecException # type: ignore
|
||||
from SpiffWorkflow.exceptions import WorkflowTaskException # type: ignore
|
||||
from SpiffWorkflow.task import Task as SpiffTask # type: ignore
|
||||
|
||||
from spiffworkflow_backend.services.process_instance_processor import (
|
||||
|
@ -54,9 +54,9 @@ class ScriptUnitTestRunner:
|
|||
offset=ex.offset,
|
||||
)
|
||||
except Exception as ex:
|
||||
if isinstance(ex, WorkflowTaskExecException):
|
||||
if isinstance(ex, WorkflowTaskException):
|
||||
# we never expect this to happen, so we want to know about it.
|
||||
# if indeed we are always getting WorkflowTaskExecException,
|
||||
# if indeed we are always getting WorkflowTaskException,
|
||||
# we can simplify this error handling and replace it with the
|
||||
# except block from revision cccd523ea39499c10f7f3c2e3f061852970973ac
|
||||
raise ex
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
"""Secret_service."""
|
||||
from typing import Optional
|
||||
|
||||
from flask_bpmn.api.api_error import ApiError
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
from spiffworkflow_backend.models.db import db
|
||||
|
||||
from spiffworkflow_backend.models.secret_model import SecretModel
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ from datetime import datetime
|
|||
from typing import List
|
||||
from typing import Optional
|
||||
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from lxml import etree # type: ignore
|
||||
from SpiffWorkflow.bpmn.parser.BpmnParser import BpmnValidator # type: ignore
|
||||
|
||||
|
@ -173,10 +173,8 @@ class SpecFileService(FileSystemService):
|
|||
parser = MyCustomParser(validator=validator)
|
||||
try:
|
||||
parser.add_bpmn_xml(etree.fromstring(binary_data), filename=file_name)
|
||||
except etree.XMLSyntaxError as exception:
|
||||
raise ProcessModelFileInvalidError(
|
||||
f"Received error trying to parse bpmn xml: {str(exception)}"
|
||||
) from exception
|
||||
except Exception as exception:
|
||||
raise ProcessModelFileInvalidError(str(exception))
|
||||
|
||||
@classmethod
|
||||
def update_file(
|
||||
|
|
|
@ -4,8 +4,8 @@ from typing import Optional
|
|||
|
||||
from flask import current_app
|
||||
from flask import g
|
||||
from flask_bpmn.api.api_error import ApiError
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
from spiffworkflow_backend.models.db import db
|
||||
|
||||
from spiffworkflow_backend.models.group import GroupModel
|
||||
from spiffworkflow_backend.models.human_task import HumanTaskModel
|
||||
|
|
|
@ -9,8 +9,8 @@ from typing import Optional
|
|||
|
||||
from flask import current_app
|
||||
from flask.testing import FlaskClient
|
||||
from flask_bpmn.api.api_error import ApiError
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
|
||||
from werkzeug.test import TestResponse # type: ignore
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ from typing import Dict
|
|||
import pytest
|
||||
from flask.app import Flask
|
||||
from flask.testing import FlaskClient
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ from typing import Optional
|
|||
import pytest
|
||||
from flask.app import Flask
|
||||
from flask.testing import FlaskClient
|
||||
from flask_bpmn.api.api_error import ApiError
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||
from werkzeug.test import TestResponse # type: ignore
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""Test_get_localtime."""
|
||||
from flask.app import Flask
|
||||
from flask.testing import FlaskClient
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import pytest
|
||||
from flask.app import Flask
|
||||
from flask.testing import FlaskClient
|
||||
from flask_bpmn.api.api_error import ApiError
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import pytest
|
||||
from flask import Flask
|
||||
from flask.testing import FlaskClient
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||
|
||||
from spiffworkflow_backend.models.message_instance import MessageInstanceModel
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""Process Model."""
|
||||
import pytest
|
||||
from flask.app import Flask
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||
|
||||
from spiffworkflow_backend.models.permission_target import (
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""Test Permissions."""
|
||||
from flask.app import Flask
|
||||
from flask.testing import FlaskClient
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ from typing import Optional
|
|||
|
||||
from flask import Flask
|
||||
from flask.testing import FlaskClient
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"""Process Model."""
|
||||
from flask.app import Flask
|
||||
from flask.testing import FlaskClient
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
import pytest
|
||||
from flask.app import Flask
|
||||
from flask.testing import FlaskClient
|
||||
from flask_bpmn.api.api_error import ApiError
|
||||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ import os
|
|||
import pytest
|
||||
from flask import Flask
|
||||
from flask.testing import FlaskClient
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
from decimal import Decimal
|
||||
|
||||
from flask.app import Flask
|
||||
from flask_bpmn.models.db import db
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
|
||||
|
||||
|
|
Loading…
Reference in New Issue