Lots of adjustments from running pyl

Main change is in the ErrorDisplay.tsx to assure all error information is provided. and index.css to make it "pretty"
This commit is contained in:
Dan 2023-01-19 12:36:45 -05:00
parent d495553968
commit 628c59dde9
78 changed files with 273 additions and 233 deletions

View File

@ -57,10 +57,17 @@ function run_autoflake() {
python_dirs=$(get_python_dirs)
python_files=$(find $python_dirs -type f -name "*.py" ! -name '.null-ls*' ! -name '_null-ls*')
echo Current dir: $(pwd)
echo dirs: $python_dirs
echo files: \"$python_files\"
if [ -z "$python_files" != ""]
then
autoflake8 --in-place --remove-unused-variables --remove-duplicate-keys --expand-star-imports --exit-zero-even-if-changed $python_files
autoflake --in-place --remove-all-unused-imports $python_files
autopep8 --in-place $python_files
else
echo "no files "
fi
}
function run_pre_commmit() {

View File

@ -1,9 +1,8 @@
"""Grabs tickets from csv and makes process instances."""
import csv
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend import get_hacked_up_app_for_script
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.services.process_instance_processor import (

View File

@ -5,11 +5,10 @@ import shutil
import pytest
from flask.app import Flask
from flask.testing import FlaskClient
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.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.human_task_user import HumanTaskUserModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.user import UserModel

View File

@ -9,16 +9,16 @@ 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 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
import spiffworkflow_backend.load_database_models # noqa: F401
from spiffworkflow_backend.config import setup_config
from spiffworkflow_backend.exceptions.api_error import api_error_blueprint
from spiffworkflow_backend.helpers.api_version import V1_API_PATH_PREFIX
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import migrate
from spiffworkflow_backend.routes.admin_blueprint.admin_blueprint import admin_blueprint
from spiffworkflow_backend.routes.openid_blueprint.openid_blueprint import (
openid_blueprint,

View File

@ -17,21 +17,21 @@ def setup_database_uri(app: Flask) -> None:
if app.config.get("SPIFFWORKFLOW_BACKEND_DATABASE_URI") is None:
database_name = f"spiffworkflow_backend_{app.config['ENV_IDENTIFIER']}"
if app.config.get("SPIFF_DATABASE_TYPE") == "sqlite":
app.config["SQLALCHEMY_DATABASE_URI"] = (
f"sqlite:///{app.instance_path}/db_{app.config['ENV_IDENTIFIER']}.sqlite3"
)
app.config[
"SQLALCHEMY_DATABASE_URI"
] = f"sqlite:///{app.instance_path}/db_{app.config['ENV_IDENTIFIER']}.sqlite3"
elif app.config.get("SPIFF_DATABASE_TYPE") == "postgres":
app.config["SQLALCHEMY_DATABASE_URI"] = (
f"postgresql://spiffworkflow_backend:spiffworkflow_backend@localhost:5432/{database_name}"
)
app.config[
"SQLALCHEMY_DATABASE_URI"
] = f"postgresql://spiffworkflow_backend:spiffworkflow_backend@localhost:5432/{database_name}"
else:
# use pswd to trick flake8 with hardcoded passwords
db_pswd = os.environ.get("DB_PASSWORD")
if db_pswd is None:
db_pswd = ""
app.config["SQLALCHEMY_DATABASE_URI"] = (
f"mysql+mysqlconnector://root:{db_pswd}@localhost/{database_name}"
)
app.config[
"SQLALCHEMY_DATABASE_URI"
] = f"mysql+mysqlconnector://root:{db_pswd}@localhost/{database_name}"
else:
app.config["SQLALCHEMY_DATABASE_URI"] = app.config.get(
"SPIFFWORKFLOW_BACKEND_DATABASE_URI"

View File

@ -102,4 +102,3 @@ permissions:
users: []
allowed_permissions: [create, read]
uri: /v1.0/user-groups/for-current-user

View File

@ -15,7 +15,8 @@ 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.exceptions import WorkflowException
from SpiffWorkflow.exceptions import WorkflowTaskException
from SpiffWorkflow.specs.base import TaskSpec # type: ignore
from SpiffWorkflow.task import Task # type: ignore
@ -40,7 +41,7 @@ class ApiError(Exception):
task_data: dict | str | None = field(default_factory=dict)
task_id: str = ""
task_name: str = ""
task_trace: dict | None = field(default_factory=dict)
task_trace: list | None = field(default_factory=dict)
def __str__(self) -> str:
"""Instructions to print instance as a string."""
@ -151,7 +152,7 @@ class ApiError(Exception):
)
else:
return ApiError.from_task_spec(error_code, message, exp.sender)
return ApiError.from_task_spec(error_code, message, exp.task_spec)
def set_user_sentry_context() -> None:
@ -176,7 +177,9 @@ def handle_exception(exception: Exception) -> flask.wrappers.Response:
if isinstance(exception, ApiError):
current_app.logger.info(
f"Sending ApiError exception to sentry: {exception} with error code {exception.error_code}")
f"Sending ApiError exception to sentry: {exception} with error code"
f" {exception.error_code}"
)
organization_slug = current_app.config.get("SENTRY_ORGANIZATION_SLUG")
project_slug = current_app.config.get("SENTRY_PROJECT_SLUG")

View File

@ -2,6 +2,7 @@
import time
import sqlalchemy
from spiffworkflow_backend.models.db import db

View File

@ -59,7 +59,8 @@ class SpiffworkflowBaseDBModel(db.Model): # type: ignore
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."""
"""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():
@ -69,7 +70,8 @@ def update_created_modified_on_create_listener(
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."""
"""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())

View File

@ -3,9 +3,11 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from spiffworkflow_backend.models.db import db, SpiffworkflowBaseDBModel
from sqlalchemy.orm import relationship
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
if TYPE_CHECKING:
from spiffworkflow_backend.models.user_group_assignment import ( # noqa: F401
UserGroupAssignmentModel,

View File

@ -4,12 +4,11 @@ from __future__ import annotations
from dataclasses import dataclass
from typing import TYPE_CHECKING
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.group import GroupModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.task import Task

View File

@ -3,11 +3,10 @@ from __future__ import annotations
from dataclasses import dataclass
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from sqlalchemy import ForeignKey
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.human_task import HumanTaskModel
from spiffworkflow_backend.models.user import UserModel

View File

@ -2,12 +2,11 @@
from dataclasses import dataclass
from typing import TYPE_CHECKING
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.message_correlation_property import (
MessageCorrelationPropertyModel,
)

View File

@ -1,11 +1,10 @@
"""Message_correlation_message_instance."""
from dataclasses import dataclass
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from sqlalchemy import ForeignKey
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.message_correlation import MessageCorrelationModel
from spiffworkflow_backend.models.message_instance import MessageInstanceModel

View File

@ -1,9 +1,8 @@
"""Message_correlation_property."""
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from sqlalchemy import ForeignKey
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.message_model import MessageModel

View File

@ -5,15 +5,14 @@ from typing import Any
from typing import Optional
from typing import TYPE_CHECKING
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
from sqlalchemy.orm import Session
from sqlalchemy.orm import validates
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.message_model import MessageModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel

View File

@ -3,7 +3,6 @@ from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
class MessageModel(SpiffworkflowBaseDBModel):
"""MessageModel."""

View File

@ -1,9 +1,8 @@
"""Message_correlation_property."""
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from sqlalchemy import ForeignKey
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.message_model import MessageModel

View File

@ -2,12 +2,11 @@
import enum
from typing import Any
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from sqlalchemy import ForeignKey
from sqlalchemy.orm import validates
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.permission_target import PermissionTargetModel
from spiffworkflow_backend.models.principal import PrincipalModel

View File

@ -3,11 +3,11 @@ import re
from dataclasses import dataclass
from typing import Optional
from sqlalchemy.orm import validates
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from sqlalchemy.orm import validates
class InvalidPermissionTargetUriError(Exception):
"""InvalidPermissionTargetUriError."""

View File

@ -1,13 +1,12 @@
"""Principal."""
from dataclasses import dataclass
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
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.group import GroupModel
from spiffworkflow_backend.models.user import UserModel

View File

@ -5,9 +5,6 @@ from typing import Any
from typing import cast
import marshmallow
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
@ -18,6 +15,8 @@ from sqlalchemy.orm import relationship
from sqlalchemy.orm import validates
from spiffworkflow_backend.helpers.spiff_enum import SpiffEnum
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.task import Task
from spiffworkflow_backend.models.task import TaskSchema
from spiffworkflow_backend.models.user import UserModel

View File

@ -1,11 +1,10 @@
"""Process_instance_metadata."""
from dataclasses import dataclass
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from sqlalchemy import ForeignKey
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel

View File

@ -7,9 +7,6 @@ from typing import cast
from typing import Optional
from typing import TypedDict
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
@ -17,6 +14,8 @@ from sqlalchemy.orm import relationship
from spiffworkflow_backend.exceptions.process_entity_not_found_error import (
ProcessEntityNotFoundError,
)
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.services.process_instance_processor import (

View File

@ -1,11 +1,11 @@
"""Refresh_token."""
from dataclasses import dataclass
from sqlalchemy import ForeignKey
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from sqlalchemy import ForeignKey
# from sqlalchemy.orm import relationship
# from spiffworkflow_backend.models.user import UserModel

View File

@ -1,12 +1,11 @@
"""Secret_model."""
from dataclasses import dataclass
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from marshmallow import Schema
from sqlalchemy import ForeignKey
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.user import UserModel

View File

@ -1,13 +1,13 @@
"""Message_model."""
from dataclasses import dataclass
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
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
class SpecReferenceNotFoundError(Exception):
"""SpecReferenceNotFoundError."""
@ -38,7 +38,8 @@ class SpecReference:
class SpecReferenceCache(SpiffworkflowBaseDBModel):
"""A cache of information about all the Processes and Decisions defined in all files."""
"""A cache of information about all the Processes and Decisions defined in all files.
"""
__tablename__ = "spec_reference_cache"
__table_args__ = (

View File

@ -6,7 +6,6 @@ from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
@dataclass
class SpiffLoggingModel(SpiffworkflowBaseDBModel):
"""SpiffLoggingModel."""

View File

@ -1,12 +1,11 @@
"""Spiff_step_details."""
from dataclasses import dataclass
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from sqlalchemy import ForeignKey
from sqlalchemy.orm import deferred
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel

View File

@ -6,12 +6,11 @@ from dataclasses import dataclass
import jwt
import marshmallow
from flask import current_app
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from marshmallow import Schema
from sqlalchemy.orm import relationship
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.group import GroupModel

View File

@ -1,10 +1,9 @@
"""UserGroupAssignment."""
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.group import GroupModel
from spiffworkflow_backend.models.user import UserModel

View File

@ -1,10 +1,9 @@
"""UserGroupAssignment."""
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.group import GroupModel

View File

@ -9,8 +9,8 @@ from flask import g
from flask import jsonify
from flask import make_response
from flask.wrappers import Response
from spiffworkflow_backend.exceptions.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
from spiffworkflow_backend.models.message_model import MessageModel

View File

@ -11,12 +11,12 @@ from flask import jsonify
from flask import make_response
from flask import request
from flask.wrappers import Response
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.exceptions.process_entity_not_found_error import (
ProcessEntityNotFoundError,
)
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.principal import PrincipalModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceModelSchema

View File

@ -8,8 +8,8 @@ from flask import g
from flask import jsonify
from flask import make_response
from flask.wrappers import Response
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.exceptions.process_entity_not_found_error import (
ProcessEntityNotFoundError,
)

View File

@ -11,12 +11,12 @@ from flask import jsonify
from flask import make_response
from flask import request
from flask.wrappers import Response
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_
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.human_task import HumanTaskModel
from spiffworkflow_backend.models.human_task_user import HumanTaskUserModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceApiSchema
@ -556,9 +556,10 @@ def process_instance_task_list(
else:
spiff_tasks = processor.get_all_user_tasks()
subprocesses_by_child_task_ids, task_typename_by_task_id = (
processor.get_subprocesses_by_child_task_ids()
)
(
subprocesses_by_child_task_ids,
task_typename_by_task_id,
) = processor.get_subprocesses_by_child_task_ids()
processor.get_highest_level_calling_subprocesses_by_child_task_ids(
subprocesses_by_child_task_ids, task_typename_by_task_id
)

View File

@ -14,9 +14,9 @@ from flask import g
from flask import jsonify
from flask import make_response
from flask.wrappers import Response
from spiffworkflow_backend.exceptions.api_error import ApiError
from werkzeug.datastructures import FileStorage
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.interfaces import IdToProcessGroupMapping
from spiffworkflow_backend.models.file import FileSchema
from spiffworkflow_backend.models.process_group import ProcessGroup

View File

@ -10,10 +10,10 @@ from flask import current_app
from flask import jsonify
from flask import make_response
from flask.wrappers import Response
from spiffworkflow_backend.exceptions.api_error import ApiError
from lxml import etree # type: ignore
from lxml.builder import ElementMaker # type: ignore
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.routes.process_api_blueprint import _get_process_model
from spiffworkflow_backend.routes.process_api_blueprint import (
_get_required_parameter_or_raise,

View File

@ -15,8 +15,6 @@ from flask import g
from flask import jsonify
from flask import make_response
from flask.wrappers import Response
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_
@ -26,6 +24,8 @@ from sqlalchemy import func
from sqlalchemy.orm import aliased
from sqlalchemy.orm.util import AliasedClass
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
from spiffworkflow_backend.models.human_task_user import HumanTaskUserModel

View File

@ -14,9 +14,9 @@ from flask import current_app
from flask import g
from flask import redirect
from flask import request
from spiffworkflow_backend.exceptions.api_error import ApiError
from werkzeug.wrappers import Response
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.services.authentication_service import AuthenticationService
from spiffworkflow_backend.services.authentication_service import (

View File

@ -7,10 +7,10 @@ import flask.wrappers
from flask import Blueprint
from flask import request
from flask import Response
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.models.db import db
from sqlalchemy.exc import IntegrityError
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.user import UserModel
from spiffworkflow_backend.models.user_group_assignment import UserGroupAssignmentModel

View File

@ -2,9 +2,9 @@
from time import time
from typing import Any
from spiffworkflow_backend.models.db import db
from sqlalchemy import or_
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.script_attributes_context import (
ScriptAttributesContext,

View File

@ -3,8 +3,8 @@ from datetime import datetime
from typing import Any
import pytz
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.models.script_attributes_context import (
ScriptAttributesContext,
)

View File

@ -2,7 +2,6 @@
from typing import Any
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.process_instance_metadata import (
ProcessInstanceMetadataModel,
)

View File

@ -9,7 +9,6 @@ from typing import Any
from typing import Callable
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceNotFoundError
from spiffworkflow_backend.models.script_attributes_context import (
@ -28,7 +27,8 @@ class ScriptUnauthorizedForUserError(Exception):
class Script:
"""Provides an abstract class that defines how scripts should work, this must be extended in all Script Tasks."""
"""Provides an abstract class that defines how scripts should work, this must be extended in all Script Tasks.
"""
@abstractmethod
def get_description(self) -> str:

View File

@ -2,9 +2,9 @@
import time
from flask import current_app
from spiffworkflow_backend.models.db import db
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus
from spiffworkflow_backend.services.process_instance_service import (

View File

@ -9,10 +9,10 @@ import jwt
import requests
from flask import current_app
from flask import redirect
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.models.db import db
from werkzeug.wrappers import Response
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.refresh_token import RefreshTokenModel
@ -60,7 +60,8 @@ class AuthenticationService:
@classmethod
def open_id_endpoint_for_name(cls, name: str) -> str:
"""All openid systems provide a mapping of static names to the full path of that endpoint."""
"""All openid systems provide a mapping of static names to the full path of that endpoint.
"""
openid_config_url = f"{cls.server_url()}/.well-known/openid-configuration"
if name not in AuthenticationService.ENDPOINT_CACHE:
response = requests.get(openid_config_url)
@ -200,7 +201,8 @@ class AuthenticationService:
@classmethod
def get_auth_token_from_refresh_token(cls, refresh_token: str) -> dict:
"""Converts a refresh token to an Auth Token by calling the openid's auth endpoint."""
"""Converts a refresh token to an Auth Token by calling the openid's auth endpoint.
"""
backend_basic_auth_string = f"{cls.client_id()}:{cls.secret_key()}"
backend_basic_auth_bytes = bytes(backend_basic_auth_string, encoding="ascii")
backend_basic_auth = base64.b64encode(backend_basic_auth_bytes)

View File

@ -17,13 +17,13 @@ from flask import current_app
from flask import g
from flask import request
from flask import scaffold
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
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.helpers.api_version import V1_API_PATH_PREFIX
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.group import GroupModel
from spiffworkflow_backend.models.human_task import HumanTaskModel
from spiffworkflow_backend.models.permission_assignment import PermissionAssignmentModel
@ -171,7 +171,8 @@ class AuthorizationService:
@classmethod
def delete_all_permissions(cls) -> None:
"""Delete_all_permissions_and_recreate. EXCEPT For permissions for the current user?"""
"""Delete_all_permissions_and_recreate. EXCEPT For permissions for the current user?
"""
for model in [PermissionAssignmentModel, PermissionTargetModel]:
db.session.query(model).delete()
@ -282,9 +283,9 @@ class AuthorizationService:
"""Find_or_create_permission_target."""
uri_with_percent = re.sub(r"\*", "%", uri)
target_uri_normalized = uri_with_percent.removeprefix(V1_API_PATH_PREFIX)
permission_target: Optional[PermissionTargetModel] = (
PermissionTargetModel.query.filter_by(uri=target_uri_normalized).first()
)
permission_target: Optional[
PermissionTargetModel
] = PermissionTargetModel.query.filter_by(uri=target_uri_normalized).first()
if permission_target is None:
permission_target = PermissionTargetModel(uri=target_uri_normalized)
db.session.add(permission_target)
@ -299,13 +300,13 @@ class AuthorizationService:
permission: str,
) -> PermissionAssignmentModel:
"""Create_permission_for_principal."""
permission_assignment: Optional[PermissionAssignmentModel] = (
PermissionAssignmentModel.query.filter_by(
permission_assignment: Optional[
PermissionAssignmentModel
] = PermissionAssignmentModel.query.filter_by(
principal_id=principal.id,
permission_target_id=permission_target.id,
permission=permission,
).first()
)
if permission_assignment is None:
permission_assignment = PermissionAssignmentModel(
principal_id=principal.id,
@ -434,10 +435,8 @@ class AuthorizationService:
except jwt.InvalidTokenError as exception:
raise ApiError(
"token_invalid",
(
"The Authentication token you provided is invalid. You need a new"
" token. "
),
" token. ",
) from exception
@staticmethod

View File

@ -15,11 +15,13 @@ class BackgroundProcessingService:
self.app = app
def process_waiting_process_instances(self) -> None:
"""Since this runs in a scheduler, we need to specify the app context as well."""
"""Since this runs in a scheduler, we need to specify the app context as well.
"""
with self.app.app_context():
ProcessInstanceService.do_waiting()
def process_message_instances_with_app_context(self) -> None:
"""Since this runs in a scheduler, we need to specify the app context as well."""
"""Since this runs in a scheduler, we need to specify the app context as well.
"""
with self.app.app_context():
MessageService.process_message_instances()

View File

@ -1,7 +1,7 @@
"""Data_setup_service."""
from flask import current_app
from spiffworkflow_backend.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

View File

@ -5,9 +5,9 @@ from typing import Union
from flask import current_app
from flask import g
from flask.wrappers import Response
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 (
MessageTriggerableProcessModel,
@ -41,7 +41,8 @@ class ErrorHandlingService:
def handle_error(
self, _processor: ProcessInstanceProcessor, _error: Union[ApiError, Exception]
) -> None:
"""On unhandled exceptions, set instance.status based on model.fault_or_suspend_on_exception."""
"""On unhandled exceptions, set instance.status based on model.fault_or_suspend_on_exception.
"""
process_model = ProcessModelService.get_process_model(
_processor.process_model_identifier
)

View File

@ -8,8 +8,8 @@ from typing import Optional
import pytz
from flask import current_app
from spiffworkflow_backend.exceptions.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
from spiffworkflow_backend.models.file import FileType
@ -151,7 +151,8 @@ class FileSystemService:
@staticmethod
def _get_files(file_path: str, file_name: Optional[str] = None) -> List[File]:
"""Returns an array of File objects at the given path, can be restricted to just one file."""
"""Returns an array of File objects at the given path, can be restricted to just one file.
"""
files = []
items = os.scandir(file_path)
for item in items:

View File

@ -2,7 +2,6 @@
from typing import Optional
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.group import GroupModel
from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.services.user_service import UserService

View File

@ -7,8 +7,8 @@ from typing import Optional
from flask import g
from flask.app import Flask
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.spiff_logging import SpiffLoggingModel
@ -52,7 +52,8 @@ class JsonFormatter(logging.Formatter):
self.datefmt = None
def usesTime(self) -> bool:
"""Overwritten to look for the attribute in the format dict values instead of the fmt string."""
"""Overwritten to look for the attribute in the format dict values instead of the fmt string.
"""
return "asctime" in self.fmt_dict.values()
# we are overriding a method that returns a string and returning a dict, hence the Any

View File

@ -2,11 +2,11 @@
from typing import Any
from typing import Optional
from spiffworkflow_backend.models.db import db
from sqlalchemy import and_
from sqlalchemy import or_
from sqlalchemy import select
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.message_correlation import MessageCorrelationModel
from spiffworkflow_backend.models.message_correlation_message_instance import (
MessageCorrelationMessageInstanceModel,

View File

@ -22,11 +22,9 @@ from uuid import UUID
import dateparser
import pytz
from flask import current_app
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.models.db import db
from lxml import etree # type: ignore
from lxml.etree import XMLSyntaxError
from RestrictedPython import safe_globals # 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
@ -40,6 +38,7 @@ from SpiffWorkflow.bpmn.workflow import BpmnWorkflow # type: ignore
from SpiffWorkflow.dmn.parser.BpmnDmnParser import BpmnDmnParser # type: ignore
from SpiffWorkflow.dmn.serializer.task_spec_converters import BusinessRuleTaskConverter # type: ignore
from SpiffWorkflow.exceptions import WorkflowException # type: ignore
from SpiffWorkflow.exceptions import WorkflowTaskException # type: ignore
from SpiffWorkflow.serializer.exceptions import MissingSpecError # type: ignore
from SpiffWorkflow.spiff.serializer.task_spec_converters import BoundaryEventConverter # type: ignore
from SpiffWorkflow.spiff.serializer.task_spec_converters import (
@ -71,6 +70,8 @@ from SpiffWorkflow.task import Task as SpiffTask # type: ignore
from SpiffWorkflow.task import TaskState
from SpiffWorkflow.util.deep_merge import DeepMerge # type: ignore
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.file import File
from spiffworkflow_backend.models.file import FileType
from spiffworkflow_backend.models.group import GroupModel
@ -217,15 +218,16 @@ class CustomBpmnScriptEngine(PythonScriptEngine): # type: ignore
return super()._evaluate(expression, context, external_methods=methods)
except Exception as exception:
if task is None:
raise ProcessInstanceProcessorError(
"Error evaluating expression: '%s', exception: %s"
raise WorkflowException(
"Error evaluating expression: '%s', %s"
% (expression, str(exception)),
) from exception
else:
raise WorkflowTaskException(
task,
"Error evaluating expression '%s', %s"
% (expression, str(exception)),
task=task,
exception=exception,
) from exception
def execute(
@ -240,7 +242,7 @@ class CustomBpmnScriptEngine(PythonScriptEngine): # type: ignore
except WorkflowException as e:
raise e
except Exception as e:
raise WorkflowTaskException(task, f" {script}, {e}", e) from e
raise self.create_task_exec_exception(task, script, e)
def call_service(
self,
@ -297,7 +299,8 @@ class ProcessInstanceProcessor:
def __init__(
self, process_instance_model: ProcessInstanceModel, validate_only: bool = False
) -> None:
"""Create a Workflow Processor based on the serialized information available in the process_instance model."""
"""Create a Workflow Processor based on the serialized information available in the process_instance model.
"""
tld = current_app.config["THREAD_LOCAL_DATA"]
tld.process_instance_id = process_instance_model.id
tld.spiff_step = process_instance_model.spiff_step
@ -403,10 +406,8 @@ class ProcessInstanceProcessor:
raise (
ApiError(
"process_model_not_found",
(
"The given process model was not found:"
f" {process_model_identifier}."
),
f" {process_model_identifier}.",
)
)
spec_files = SpecFileService.get_files(process_model_info)
@ -536,11 +537,9 @@ class ProcessInstanceProcessor:
potential_owner_ids.append(lane_owner_user.id)
self.raise_if_no_potential_owners(
potential_owner_ids,
(
"No users found in task data lane owner list for lane:"
f" {task_lane}. The user list used:"
f" {task.data['lane_owners'][task_lane]}"
),
f" {task.data['lane_owners'][task_lane]}",
)
else:
group_model = GroupModel.query.filter_by(identifier=task_lane).first()
@ -693,9 +692,9 @@ class ProcessInstanceProcessor:
):
continue
subprocesses_by_child_task_ids[task_id] = (
subprocesses_by_child_task_ids[subprocess_id]
)
subprocesses_by_child_task_ids[
task_id
] = subprocesses_by_child_task_ids[subprocess_id]
self.get_highest_level_calling_subprocesses_by_child_task_ids(
subprocesses_by_child_task_ids, task_typename_by_task_id
)
@ -1015,17 +1014,24 @@ class ProcessInstanceProcessor:
def get_spec(
files: List[File], process_model_info: ProcessModelInfo
) -> Tuple[BpmnProcessSpec, IdToBpmnProcessSpecMapping]:
"""Returns a SpiffWorkflow specification for the given process_instance spec, using the files provided."""
"""Returns a SpiffWorkflow specification for the given process_instance spec, using the files provided.
"""
parser = ProcessInstanceProcessor.get_parser()
for file in files:
data = SpecFileService.get_data(process_model_info, file.name)
try:
if file.type == FileType.bpmn.value:
bpmn: etree.Element = etree.fromstring(data)
parser.add_bpmn_xml(bpmn, filename=file.name)
elif file.type == FileType.dmn.value:
dmn: etree.Element = etree.fromstring(data)
parser.add_dmn_xml(dmn, filename=file.name)
except XMLSyntaxError as xse:
raise ApiError(
error_code="invalid_xml",
message=f"'{file.name}' is not a valid xml file." + str(xse),
)
if (
process_model_info.primary_process_id is None
or process_model_info.primary_process_id == ""
@ -1056,7 +1062,8 @@ class ProcessInstanceProcessor:
error_code="process_instance_validation_error",
message="Failed to parse the Workflow Specification. "
+ "Error is '%s.'" % str(ve),
file_name=ve.filename,
file_name=ve.file_name,
task_name=ve.name,
task_id=ve.id,
tag=ve.tag,
) from ve
@ -1097,10 +1104,8 @@ class ProcessInstanceProcessor:
if not bpmn_message.correlations:
raise ApiError(
"message_correlations_missing",
(
"Could not find any message correlations bpmn_message:"
f" {bpmn_message.name}"
),
f" {bpmn_message.name}",
)
message_correlations = []
@ -1120,10 +1125,8 @@ class ProcessInstanceProcessor:
if message_correlation_property is None:
raise ApiError(
"message_correlations_missing_from_process",
(
"Could not find a known message correlation with"
f" identifier:{message_correlation_property_identifier}"
),
f" identifier:{message_correlation_property_identifier}",
)
message_correlations.append(
{
@ -1186,10 +1189,8 @@ class ProcessInstanceProcessor:
if message_model is None:
raise ApiError(
"invalid_message_name",
(
"Invalid message name:"
f" {waiting_task.task_spec.event_definition.name}."
),
f" {waiting_task.task_spec.event_definition.name}.",
)
# Ensure we are only creating one message instance for each waiting message
@ -1474,7 +1475,8 @@ class ProcessInstanceProcessor:
return self.bpmn_process_instance.get_ready_user_tasks() # type: ignore
def get_current_user_tasks(self) -> list[SpiffTask]:
"""Return a list of all user tasks that are READY or COMPLETE and are parallel to the READY Task."""
"""Return a list of all user tasks that are READY or COMPLETE and are parallel to the READY Task.
"""
ready_tasks = self.bpmn_process_instance.get_ready_user_tasks()
additional_tasks = []
if len(ready_tasks) > 0:
@ -1531,7 +1533,8 @@ class ProcessInstanceProcessor:
return None
def find_spec_and_field(self, spec_name: str, field_id: Union[str, int]) -> Any:
"""Tracks down a form field by name in the process_instance spec(s), Returns a tuple of the task, and form."""
"""Tracks down a form field by name in the process_instance spec(s), Returns a tuple of the task, and form.
"""
process_instances = [self.bpmn_process_instance]
for task in self.bpmn_process_instance.get_ready_user_tasks():
if task.process_instance not in process_instances:

View File

@ -6,15 +6,14 @@ from typing import Optional
from typing import Type
import sqlalchemy
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_
from sqlalchemy.orm import aliased
from sqlalchemy.orm import selectinload
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.group import GroupModel
from spiffworkflow_backend.models.human_task import HumanTaskModel
from spiffworkflow_backend.models.human_task_user import HumanTaskUserModel
@ -313,9 +312,9 @@ class ProcessInstanceReportService:
process_instance_dict = process_instance["ProcessInstanceModel"].serialized
for metadata_column in metadata_columns:
if metadata_column["accessor"] not in process_instance_dict:
process_instance_dict[metadata_column["accessor"]] = (
process_instance[metadata_column["accessor"]]
)
process_instance_dict[
metadata_column["accessor"]
] = process_instance[metadata_column["accessor"]]
results.append(process_instance_dict)
return results

View File

@ -5,10 +5,10 @@ from typing import List
from typing import Optional
from flask import current_app
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.exceptions.api_error import ApiError
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.human_task import HumanTaskModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceApi
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
@ -224,7 +224,8 @@ class ProcessInstanceService:
@staticmethod
def extract_form_data(latest_data: dict, task: SpiffTask) -> dict:
"""Extracts data from the latest_data that is directly related to the form that is being submitted."""
"""Extracts data from the latest_data that is directly related to the form that is being submitted.
"""
data = {}
if hasattr(task.task_spec, "form"):

View File

@ -9,7 +9,6 @@ from typing import Optional
from typing import TypeVar
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.exceptions.process_entity_not_found_error import (
ProcessEntityNotFoundError,
)

View File

@ -3,7 +3,6 @@ from typing import Optional
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.secret_model import SecretModel
# from cryptography.fernet import Fernet

View File

@ -5,10 +5,10 @@ from datetime import datetime
from typing import List
from typing import Optional
from spiffworkflow_backend.models.db import db
from lxml import etree # type: ignore
from SpiffWorkflow.bpmn.parser.BpmnParser import BpmnValidator # type: ignore
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.file import File
from spiffworkflow_backend.models.file import FileType
from spiffworkflow_backend.models.file import SpecReference
@ -325,7 +325,8 @@ class SpecFileService(FileSystemService):
@staticmethod
def update_message_cache(ref: SpecReference) -> None:
"""Assure we have a record in the database of all possible message ids and names."""
"""Assure we have a record in the database of all possible message ids and names.
"""
for message_model_identifier in ref.messages.keys():
message_model = MessageModel.query.filter_by(
identifier=message_model_identifier

View File

@ -4,9 +4,9 @@ from typing import Optional
from flask import current_app
from flask import g
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
from spiffworkflow_backend.models.human_task_user import HumanTaskUserModel

View File

@ -9,11 +9,11 @@ from typing import Optional
from flask import current_app
from flask.testing import FlaskClient
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
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.permission_assignment import Permission
from spiffworkflow_backend.models.permission_target import PermissionTargetModel
from spiffworkflow_backend.models.process_group import ProcessGroup

View File

@ -40,7 +40,8 @@ def load_test_spec(
bpmn_file_name: Optional[str] = None,
process_model_source_directory: Optional[str] = None,
) -> ProcessModelInfo:
"""Loads a bpmn file into the process model dir based on a directory in tests/data."""
"""Loads a bpmn file into the process model dir based on a directory in tests/data.
"""
if process_model_source_directory is None:
raise Exception("You must inclode a `process_model_source_directory`.")

View File

@ -9,13 +9,13 @@ from typing import Dict
import pytest
from flask.app import Flask
from flask.testing import FlaskClient
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
from spiffworkflow_backend.exceptions.process_entity_not_found_error import (
ProcessEntityNotFoundError,
)
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.group import GroupModel
from spiffworkflow_backend.models.human_task import HumanTaskModel
from spiffworkflow_backend.models.process_group import ProcessGroup
@ -3103,7 +3103,8 @@ class TestProcessApi(BaseTest):
with_db_and_bpmn_file_cleanup: None,
with_super_admin_user: UserModel,
) -> None:
"""Test_can_get_process_instance_list_with_report_metadata_and_process_initator."""
"""Test_can_get_process_instance_list_with_report_metadata_and_process_initator.
"""
user_one = self.create_user_with_permission(username="user_one")
process_model = load_test_spec(

View File

@ -5,10 +5,10 @@ from typing import Optional
import pytest
from flask.app import Flask
from flask.testing import FlaskClient
from spiffworkflow_backend.exceptions.api_error import ApiError
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
from werkzeug.test import TestResponse # type: ignore
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.models.process_model import ProcessModelInfo
from spiffworkflow_backend.models.secret_model import SecretModel
from spiffworkflow_backend.models.secret_model import SecretModelSchema

View File

@ -1,10 +1,10 @@
"""Test_get_localtime."""
from flask.app import Flask
from flask.testing import FlaskClient
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
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.group import GroupModel
from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.services.process_instance_processor import (

View File

@ -2,10 +2,10 @@
import pytest
from flask.app import Flask
from flask.testing import FlaskClient
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
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.services.process_instance_processor import (
ProcessInstanceProcessor,
)

View File

@ -2,9 +2,9 @@
import pytest
from flask import Flask
from flask.testing import FlaskClient
from spiffworkflow_backend.models.db import db
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.message_instance import MessageInstanceModel
from spiffworkflow_backend.models.message_model import MessageModel
from spiffworkflow_backend.models.user import UserModel

View File

@ -1,9 +1,9 @@
"""Process Model."""
import pytest
from flask.app import Flask
from spiffworkflow_backend.models.db import db
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.permission_target import (
InvalidPermissionTargetUriError,
)

View File

@ -1,10 +1,10 @@
"""Test Permissions."""
from flask.app import Flask
from flask.testing import FlaskClient
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
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.group import GroupModel
from spiffworkflow_backend.models.permission_assignment import PermissionAssignmentModel
from spiffworkflow_backend.models.permission_target import PermissionTargetModel

View File

@ -3,10 +3,10 @@ from typing import Optional
from flask import Flask
from flask.testing import FlaskClient
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
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.group import GroupModel
from spiffworkflow_backend.models.human_task import HumanTaskModel
from spiffworkflow_backend.models.process_instance_report import (

View File

@ -1,10 +1,10 @@
"""Process Model."""
from flask.app import Flask
from flask.testing import FlaskClient
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
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.process_instance_metadata import (
ProcessInstanceMetadataModel,
)

View File

@ -2,10 +2,10 @@
import pytest
from flask.app import Flask
from flask.testing import FlaskClient
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
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.services.process_instance_processor import (
ProcessInstanceProcessor,

View File

@ -4,10 +4,10 @@ import os
import pytest
from flask import Flask
from flask.testing import FlaskClient
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
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.spec_reference import SpecReferenceCache
from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.services.process_model_service import ProcessModelService
@ -136,7 +136,8 @@ class TestSpecFileService(BaseTest):
with_db_and_bpmn_file_cleanup: None,
with_super_admin_user: UserModel,
) -> None:
"""When a BPMN processes identifier is changed in a file, the old id is removed from the cache."""
"""When a BPMN processes identifier is changed in a file, the old id is removed from the cache.
"""
old_identifier = "ye_old_identifier"
process_id_lookup = SpecReferenceCache(
identifier=old_identifier,

View File

@ -2,10 +2,10 @@
from decimal import Decimal
from flask.app import Flask
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
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.spiff_logging import SpiffLoggingModel

View File

@ -2,6 +2,23 @@ import { useContext } from 'react';
import ErrorContext from '../contexts/ErrorContext';
import { Notification } from './Notification';
function errorDetailDisplay(
errorObject: any,
propertyName: string,
title: string
) {
// Creates a bit of html for displaying a single error property if it exists.
if (propertyName in errorObject && errorObject[propertyName]) {
return (
<div className="error_info">
<span className="error_title">{title}:</span>
{errorObject[propertyName]}
</div>
);
}
return null;
}
export default function ErrorDisplay() {
const [errorObject, setErrorObject] = (useContext as any)(ErrorContext);
@ -21,21 +38,24 @@ export default function ErrorDisplay() {
);
}
let message = <div>{errorObject.message}</div>;
let title = 'Error:';
if ('task_name' in errorObject && errorObject.task_name) {
title = 'Error in python script:';
message = (
<>
<br />
<div>
Task: {errorObject.task_name} ({errorObject.task_id})
const message = <div>{errorObject.message}</div>;
const title = 'Error:';
const taskName = errorDetailDisplay(errorObject, 'task_name', 'Task Name');
const taskId = errorDetailDisplay(errorObject, 'task_id', 'Task ID');
const fileName = errorDetailDisplay(errorObject, 'file_name', 'File Name');
const lineNumber = errorDetailDisplay(
errorObject,
'line_number',
'Line Number'
);
const errorLine = errorDetailDisplay(errorObject, 'error_line', 'Context');
let taskTrace = null;
if ('task_trace' in errorObject && errorObject.task_trace.length > 1) {
taskTrace = (
<div className="error_info">
<span className="error_title">Call Activity Trace:</span>
{errorObject.task_trace.reverse().join(' -> ')}
</div>
<div>File name: {errorObject.file_name}</div>
<div>Line number in script task: {errorObject.line_number}</div>
<br />
<div>{errorObject.message}</div>
</>
);
}
@ -46,7 +66,14 @@ export default function ErrorDisplay() {
type="error"
>
{message}
<br />
{sentryLinkTag}
{taskName}
{taskId}
{fileName}
{lineNumber}
{errorLine}
{taskTrace}
</Notification>
);
}

View File

@ -374,3 +374,12 @@ svg.notification-icon {
.tag-type-green:hover {
background-color: #80ee90;
}
/* Errors and notifications */
.error_info .error_title {
display: inline-block;
font-weight: lighter;
width: 100px;
text-align: right;
margin-right: 10px;
}