Merge remote-tracking branch 'origin/main' into feature/fix_process_instance_rewind
This commit is contained in:
commit
fa4d19916b
|
@ -16,10 +16,7 @@ jobs:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
# FIXME: https://github.com/mysql/mysql-connector-python/pull/86
|
- { python: "3.11", os: "ubuntu-latest", session: "safety" }
|
||||||
# put back when poetry update protobuf mysql-connector-python updates protobuf
|
|
||||||
# right now mysql is forcing protobuf to version 3
|
|
||||||
# - { python: "3.11", os: "ubuntu-latest", session: "safety" }
|
|
||||||
- { python: "3.11", os: "ubuntu-latest", session: "mypy" }
|
- { python: "3.11", os: "ubuntu-latest", session: "mypy" }
|
||||||
- { python: "3.10", os: "ubuntu-latest", session: "mypy" }
|
- { python: "3.10", os: "ubuntu-latest", session: "mypy" }
|
||||||
- { python: "3.9", os: "ubuntu-latest", session: "mypy" }
|
- { python: "3.9", os: "ubuntu-latest", session: "mypy" }
|
||||||
|
@ -176,6 +173,19 @@ jobs:
|
||||||
name: logs-${{matrix.python}}-${{matrix.os}}-${{matrix.database}}
|
name: logs-${{matrix.python}}-${{matrix.os}}-${{matrix.database}}
|
||||||
path: "./log/*.log"
|
path: "./log/*.log"
|
||||||
|
|
||||||
|
# burnettk created an account at https://app.snyk.io/org/kevin-jfx
|
||||||
|
# and added his SNYK_TOKEN secret under the spiff-arena repo.
|
||||||
|
snyk:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@master
|
||||||
|
- name: Run Snyk to check for vulnerabilities
|
||||||
|
uses: snyk/actions/python@master
|
||||||
|
with:
|
||||||
|
args: spiffworkflow-backend
|
||||||
|
env:
|
||||||
|
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||||
|
|
||||||
run_pre_commit_checks:
|
run_pre_commit_checks:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
defaults:
|
defaults:
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
pyrightconfig.json
|
pyrightconfig.json
|
||||||
.idea/
|
.idea/
|
||||||
t
|
t
|
||||||
|
.dccache
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
125
pyproject.toml
125
pyproject.toml
|
@ -13,71 +13,8 @@ classifiers = [
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = ">=3.11,<3.12"
|
python = ">=3.11,<3.12"
|
||||||
click = "^8.0.1"
|
|
||||||
flask = "2.2.2"
|
|
||||||
flask-admin = "*"
|
|
||||||
flask-bcrypt = "*"
|
|
||||||
flask-cors = "*"
|
|
||||||
flask-mail = "*"
|
|
||||||
flask-marshmallow = "*"
|
|
||||||
flask-migrate = "*"
|
|
||||||
flask-restful = "*"
|
|
||||||
werkzeug = "*"
|
|
||||||
# go back to main once https://github.com/sartography/SpiffWorkflow/pull/241 is merged
|
|
||||||
SpiffWorkflow = {git = "https://github.com/sartography/SpiffWorkflow", rev = "main"}
|
|
||||||
# SpiffWorkflow = {develop = true, path = "/Users/kevin/projects/github/sartography/SpiffWorkflow"}
|
|
||||||
# SpiffWorkflow = {develop = true, path = "/home/jason/projects/github/sartography/SpiffWorkflow"}
|
|
||||||
sentry-sdk = "^1.10"
|
|
||||||
sphinx-autoapi = "^2.0"
|
|
||||||
# flask-bpmn = {develop = true, path = "/home/jason/projects/github/sartography/flask-bpmn"}
|
|
||||||
# flask-bpmn = {develop = true, path = "/Users/kevin/projects/github/sartography/flask-bpmn"}
|
|
||||||
flask-bpmn = {git = "https://github.com/sartography/flask-bpmn", rev = "main"}
|
|
||||||
mysql-connector-python = "^8.0.29"
|
|
||||||
pytest-flask = "^1.2.0"
|
|
||||||
pytest-flask-sqlalchemy = "^1.1.0"
|
|
||||||
psycopg2 = "^2.9.3"
|
|
||||||
typing-extensions = "^4.4.0"
|
|
||||||
connexion = {extras = [ "swagger-ui",], version = "^2"}
|
|
||||||
lxml = "^4.9.1"
|
|
||||||
marshmallow-enum = "^1.5.1"
|
|
||||||
marshmallow-sqlalchemy = "^0.28.0"
|
|
||||||
PyJWT = "^2.6.0"
|
|
||||||
gunicorn = "^20.1.0"
|
|
||||||
python-keycloak = "^2.5.0"
|
|
||||||
APScheduler = "^3.9.1"
|
|
||||||
Jinja2 = "^3.1.2"
|
|
||||||
RestrictedPython = "^6.0"
|
|
||||||
Flask-SQLAlchemy = "^3"
|
|
||||||
|
|
||||||
# type hinting stuff
|
|
||||||
# these need to be in the normal (non dev-dependencies) section
|
|
||||||
# because if not then poetry export won't have them and nox -s mypy --pythons 3.10
|
|
||||||
# will fail
|
|
||||||
types-Werkzeug = "^1.0.9"
|
|
||||||
types-PyYAML = "^6.0.12"
|
|
||||||
types-Flask = "^1.1.6"
|
|
||||||
types-requests = "^2.28.6"
|
|
||||||
types-pytz = "^2022.1.1"
|
|
||||||
|
|
||||||
# https://github.com/dropbox/sqlalchemy-stubs/pull/251
|
|
||||||
# someday get off github
|
|
||||||
# sqlalchemy-stubs = "^0.4"
|
|
||||||
# sqlalchemy-stubs = { git = "https://github.com/dropbox/sqlalchemy-stubs.git", rev = "master" }
|
|
||||||
# sqlalchemy-stubs = {develop = true, path = "/Users/kevin/projects/github/sqlalchemy-stubs"}
|
|
||||||
# for now use my fork
|
|
||||||
sqlalchemy-stubs = { git = "https://github.com/burnettk/sqlalchemy-stubs.git", rev = "scoped-session-delete" }
|
|
||||||
simplejson = "^3.17.6"
|
|
||||||
|
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
pytest = "^7.1.2"
|
|
||||||
coverage = {extras = ["toml"], version = "^6.1"}
|
|
||||||
safety = "^2.3.1"
|
|
||||||
mypy = ">=0.961"
|
|
||||||
typeguard = "^2.13.2"
|
|
||||||
xdoctest = {extras = ["colors"], version = "^1.0.1"}
|
|
||||||
sphinx = "^5.0.2"
|
|
||||||
sphinx-autobuild = ">=2021.3.14"
|
|
||||||
pre-commit = "^2.20.0"
|
pre-commit = "^2.20.0"
|
||||||
flake8 = "^4.0.1"
|
flake8 = "^4.0.1"
|
||||||
black = ">=21.10b0"
|
black = ">=21.10b0"
|
||||||
|
@ -89,71 +26,9 @@ bandit = "1.7.2"
|
||||||
flake8-bugbear = "^22.10.25"
|
flake8-bugbear = "^22.10.25"
|
||||||
flake8-docstrings = "^1.6.0"
|
flake8-docstrings = "^1.6.0"
|
||||||
flake8-rst-docstrings = "^0.2.7"
|
flake8-rst-docstrings = "^0.2.7"
|
||||||
# flask-sqlalchemy-stubs = "^0.2"
|
|
||||||
pep8-naming = "^0.13.2"
|
|
||||||
darglint = "^1.8.1"
|
|
||||||
reorder-python-imports = "^3.9.0"
|
reorder-python-imports = "^3.9.0"
|
||||||
pre-commit-hooks = "^4.0.1"
|
pre-commit-hooks = "^4.0.1"
|
||||||
sphinx-click = "^4.3.0"
|
|
||||||
Pygments = "^2.10.0"
|
|
||||||
pyupgrade = "^3.1.0"
|
pyupgrade = "^3.1.0"
|
||||||
furo = ">=2021.11.12"
|
|
||||||
|
|
||||||
[tool.poetry.scripts]
|
|
||||||
spiffworkflow-backend = "spiffworkflow_backend.__main__:main"
|
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
tomli = "^2.0.1"
|
tomli = "^2.0.1"
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
|
||||||
# ignore deprecation warnings from various packages that we don't control
|
|
||||||
filterwarnings = [
|
|
||||||
# note the use of single quote below to denote "raw" strings in TOML
|
|
||||||
# kombu/utils/compat.py:82
|
|
||||||
'ignore:SelectableGroups dict interface is deprecated. Use select.',
|
|
||||||
# flask_marshmallow/__init__.py:34
|
|
||||||
# marshmallow_sqlalchemy/convert.py:17
|
|
||||||
'ignore:distutils Version classes are deprecated. Use packaging.version instead.',
|
|
||||||
# connexion/spec.py:50
|
|
||||||
'ignore:Passing a schema to Validator.iter_errors is deprecated and will be removed in a future release',
|
|
||||||
# connexion/decorators/validation.py:16
|
|
||||||
'ignore:Accessing jsonschema.draft4_format_checker is deprecated and will be removed in a future release.',
|
|
||||||
# connexion/apis/flask_api.py:236
|
|
||||||
"ignore:'_request_ctx_stack' is deprecated and will be removed in Flask 2.3",
|
|
||||||
"ignore:Setting 'json_encoder' on the app or a blueprint is deprecated and will be removed in Flask 2.3",
|
|
||||||
"ignore:'JSONEncoder' is deprecated and will be removed in Flask 2.3",
|
|
||||||
"ignore:'app.json_encoder' is deprecated and will be removed in Flask 2.3"
|
|
||||||
]
|
|
||||||
|
|
||||||
[tool.coverage.paths]
|
|
||||||
source = ["src", "*/site-packages"]
|
|
||||||
tests = ["tests", "*/tests"]
|
|
||||||
|
|
||||||
[tool.coverage.run]
|
|
||||||
branch = true
|
|
||||||
source = ["spiffworkflow_backend", "tests"]
|
|
||||||
|
|
||||||
[tool.coverage.report]
|
|
||||||
show_missing = true
|
|
||||||
fail_under = 50
|
|
||||||
|
|
||||||
[tool.mypy]
|
|
||||||
strict = true
|
|
||||||
disallow_any_generics = false
|
|
||||||
warn_unreachable = true
|
|
||||||
pretty = true
|
|
||||||
show_column_numbers = true
|
|
||||||
show_error_codes = true
|
|
||||||
show_error_context = true
|
|
||||||
plugins = "sqlmypy"
|
|
||||||
|
|
||||||
# We get 'error: Module has no attribute "set_context"' for sentry-sdk without this option
|
|
||||||
implicit_reexport = true
|
|
||||||
|
|
||||||
# allow for subdirs to NOT require __init__.py
|
|
||||||
namespace_packages = true
|
|
||||||
explicit_package_bases = false
|
|
||||||
|
|
||||||
[build-system]
|
|
||||||
requires = ["poetry-core>=1.0.0"]
|
|
||||||
build-backend = "poetry.core.masonry.api"
|
|
||||||
|
|
|
@ -44,6 +44,17 @@ if [[ "${1:-}" == "clean" ]]; then
|
||||||
# TODO: check to see if the db already exists and we can connect to it. also actually clean it up.
|
# TODO: check to see if the db already exists and we can connect to it. also actually clean it up.
|
||||||
# start postgres in background with one db
|
# start postgres in background with one db
|
||||||
if [[ "${SPIFFWORKFLOW_BACKEND_DATABASE_TYPE:-}" == "postgres" ]]; then
|
if [[ "${SPIFFWORKFLOW_BACKEND_DATABASE_TYPE:-}" == "postgres" ]]; then
|
||||||
|
container_name="postgres-spiff"
|
||||||
|
container_regex="^postgres-spiff$"
|
||||||
|
if [[ -n "$(docker ps -qa -f name=$container_regex)" ]]; then
|
||||||
|
echo ":: Found postgres container - $container_name"
|
||||||
|
if [[ -n "$(docker ps -q -f name=$container_regex)" ]]; then
|
||||||
|
echo ":: Stopping running container - $container_name"
|
||||||
|
docker stop $container_name
|
||||||
|
fi
|
||||||
|
echo ":: Removing stopped container - $container_name"
|
||||||
|
docker rm $container_name
|
||||||
|
fi
|
||||||
if ! docker exec -it postgres-spiff psql -U spiffworkflow_backend spiffworkflow_backend_unit_testing -c "select 1"; then
|
if ! docker exec -it postgres-spiff psql -U spiffworkflow_backend spiffworkflow_backend_unit_testing -c "select 1"; then
|
||||||
docker run --name postgres-spiff -p 5432:5432 -e POSTGRES_PASSWORD=spiffworkflow_backend -e POSTGRES_USER=spiffworkflow_backend -e POSTGRES_DB=spiffworkflow_backend_unit_testing -d postgres
|
docker run --name postgres-spiff -p 5432:5432 -e POSTGRES_PASSWORD=spiffworkflow_backend -e POSTGRES_USER=spiffworkflow_backend -e POSTGRES_DB=spiffworkflow_backend_unit_testing -d postgres
|
||||||
sleep 4 # classy
|
sleep 4 # classy
|
||||||
|
|
|
@ -45,8 +45,8 @@ def app() -> Flask:
|
||||||
def with_db_and_bpmn_file_cleanup() -> None:
|
def with_db_and_bpmn_file_cleanup() -> None:
|
||||||
"""Do it cleanly!"""
|
"""Do it cleanly!"""
|
||||||
meta = db.metadata
|
meta = db.metadata
|
||||||
db.session.execute(db.update(BpmnProcessModel, values={"top_level_process_id": None}))
|
db.session.execute(db.update(BpmnProcessModel).values(top_level_process_id=None))
|
||||||
db.session.execute(db.update(BpmnProcessModel, values={"direct_parent_process_id": None}))
|
db.session.execute(db.update(BpmnProcessModel).values(direct_parent_process_id=None))
|
||||||
|
|
||||||
for table in reversed(meta.sorted_tables):
|
for table in reversed(meta.sorted_tables):
|
||||||
db.session.execute(table.delete())
|
db.session.execute(table.delete())
|
||||||
|
|
|
@ -26,9 +26,10 @@ fi
|
||||||
|
|
||||||
# https://stackoverflow.com/a/60579344/6090676
|
# https://stackoverflow.com/a/60579344/6090676
|
||||||
container_name="keycloak"
|
container_name="keycloak"
|
||||||
if [[ -n "$(docker ps -qa -f name=$container_name)" ]]; then
|
container_regex="^keycloak$"
|
||||||
|
if [[ -n "$(docker ps -qa -f name=$container_regex)" ]]; then
|
||||||
echo ":: Found container - $container_name"
|
echo ":: Found container - $container_name"
|
||||||
if [[ -n "$(docker ps -q -f name=$container_name)" ]]; then
|
if [[ -n "$(docker ps -q -f name=$container_regex)" ]]; then
|
||||||
echo ":: Stopping running container - $container_name"
|
echo ":: Stopping running container - $container_name"
|
||||||
docker stop $container_name
|
docker stop $container_name
|
||||||
fi
|
fi
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -39,10 +39,16 @@ pytest-flask = "^1.2.0"
|
||||||
pytest-flask-sqlalchemy = "^1.1.0"
|
pytest-flask-sqlalchemy = "^1.1.0"
|
||||||
psycopg2 = "^2.9.3"
|
psycopg2 = "^2.9.3"
|
||||||
typing-extensions = "^4.4.0"
|
typing-extensions = "^4.4.0"
|
||||||
|
|
||||||
|
# pinned to higher than 65.5.0 because of a vulnerability
|
||||||
|
# and to lower than 67 because i didn't feel like addressing
|
||||||
|
# new deprecation warnings. we don't need this library explicitly,
|
||||||
|
# but at one time it was pulled in by various libs we depend on.
|
||||||
|
setuptools = "^65.5.1"
|
||||||
|
|
||||||
connexion = {extras = [ "swagger-ui",], version = "^2"}
|
connexion = {extras = [ "swagger-ui",], version = "^2"}
|
||||||
lxml = "^4.9.1"
|
lxml = "^4.9.1"
|
||||||
marshmallow-enum = "^1.5.1"
|
marshmallow-enum = "^1.5.1"
|
||||||
marshmallow-sqlalchemy = "^0.28.0"
|
|
||||||
PyJWT = "^2.6.0"
|
PyJWT = "^2.6.0"
|
||||||
gunicorn = "^20.1.0"
|
gunicorn = "^20.1.0"
|
||||||
APScheduler = "*"
|
APScheduler = "*"
|
||||||
|
@ -75,7 +81,9 @@ flask-jwt-extended = "^4.4.4"
|
||||||
pylint = "^2.15.10"
|
pylint = "^2.15.10"
|
||||||
flask-simple-crypt = "^0.3.3"
|
flask-simple-crypt = "^0.3.3"
|
||||||
cryptography = "^39.0.2"
|
cryptography = "^39.0.2"
|
||||||
|
safety = "^2.3.5"
|
||||||
|
sqlalchemy = "^2.0.7"
|
||||||
|
marshmallow-sqlalchemy = "^0.29.0"
|
||||||
|
|
||||||
[tool.poetry.dev-dependencies]
|
[tool.poetry.dev-dependencies]
|
||||||
pytest = "^7.1.2"
|
pytest = "^7.1.2"
|
||||||
|
|
|
@ -44,8 +44,9 @@ class MyJSONEncoder(DefaultJSONProvider):
|
||||||
return obj.serialized
|
return obj.serialized
|
||||||
elif isinstance(obj, sqlalchemy.engine.row.Row): # type: ignore
|
elif isinstance(obj, sqlalchemy.engine.row.Row): # type: ignore
|
||||||
return_dict = {}
|
return_dict = {}
|
||||||
for row_key in obj.keys():
|
row_mapping = obj._mapping
|
||||||
row_value = obj[row_key]
|
for row_key in row_mapping.keys():
|
||||||
|
row_value = row_mapping[row_key]
|
||||||
if hasattr(row_value, "serialized"):
|
if hasattr(row_value, "serialized"):
|
||||||
return_dict.update(row_value.serialized)
|
return_dict.update(row_value.serialized)
|
||||||
elif hasattr(row_value, "__dict__"):
|
elif hasattr(row_value, "__dict__"):
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import time
|
import time
|
||||||
|
|
||||||
import sqlalchemy
|
import sqlalchemy
|
||||||
|
from sqlalchemy.sql import text
|
||||||
|
|
||||||
from spiffworkflow_backend.models.db import db
|
from spiffworkflow_backend.models.db import db
|
||||||
|
|
||||||
|
@ -9,7 +10,7 @@ from spiffworkflow_backend.models.db import db
|
||||||
def try_to_connect(start_time: float) -> None:
|
def try_to_connect(start_time: float) -> None:
|
||||||
"""Try to connect."""
|
"""Try to connect."""
|
||||||
try:
|
try:
|
||||||
db.first_or_404("select 1") # type: ignore
|
db.first_or_404(text("select 1")) # type: ignore
|
||||||
except sqlalchemy.exc.DatabaseError as exception:
|
except sqlalchemy.exc.DatabaseError as exception:
|
||||||
if time.time() - start_time > 15:
|
if time.time() - start_time > 15:
|
||||||
raise exception
|
raise exception
|
||||||
|
|
|
@ -53,6 +53,7 @@ class ProcessInstanceModel(SpiffworkflowBaseDBModel):
|
||||||
"""ProcessInstanceModel."""
|
"""ProcessInstanceModel."""
|
||||||
|
|
||||||
__tablename__ = "process_instance"
|
__tablename__ = "process_instance"
|
||||||
|
__allow_unmapped__ = True
|
||||||
id: int = db.Column(db.Integer, primary_key=True)
|
id: int = db.Column(db.Integer, primary_key=True)
|
||||||
process_model_identifier: str = db.Column(db.String(255), nullable=False, index=True)
|
process_model_identifier: str = db.Column(db.String(255), nullable=False, index=True)
|
||||||
process_model_display_name: str = db.Column(db.String(255), nullable=False, index=True)
|
process_model_display_name: str = db.Column(db.String(255), nullable=False, index=True)
|
||||||
|
|
|
@ -8,7 +8,6 @@ from typing import Optional
|
||||||
from typing import TypedDict
|
from typing import TypedDict
|
||||||
|
|
||||||
from sqlalchemy import ForeignKey
|
from sqlalchemy import ForeignKey
|
||||||
from sqlalchemy.orm import deferred
|
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
|
|
||||||
from spiffworkflow_backend.exceptions.process_entity_not_found_error import (
|
from spiffworkflow_backend.exceptions.process_entity_not_found_error import (
|
||||||
|
@ -69,7 +68,7 @@ class ProcessInstanceReportModel(SpiffworkflowBaseDBModel):
|
||||||
|
|
||||||
id: int = db.Column(db.Integer, primary_key=True)
|
id: int = db.Column(db.Integer, primary_key=True)
|
||||||
identifier: str = db.Column(db.String(50), nullable=False, index=True)
|
identifier: str = db.Column(db.String(50), nullable=False, index=True)
|
||||||
report_metadata: dict = deferred(db.Column(db.JSON)) # type: ignore
|
report_metadata: dict = db.Column(db.JSON)
|
||||||
created_by_id = db.Column(ForeignKey(UserModel.id), nullable=False, index=True) # type: ignore
|
created_by_id = db.Column(ForeignKey(UserModel.id), nullable=False, index=True) # type: ignore
|
||||||
created_by = relationship("UserModel")
|
created_by = relationship("UserModel")
|
||||||
created_at_in_seconds = db.Column(db.Integer)
|
created_at_in_seconds = db.Column(db.Integer)
|
||||||
|
|
|
@ -47,6 +47,7 @@ class MultiInstanceType(enum.Enum):
|
||||||
@dataclass
|
@dataclass
|
||||||
class TaskModel(SpiffworkflowBaseDBModel):
|
class TaskModel(SpiffworkflowBaseDBModel):
|
||||||
__tablename__ = "task"
|
__tablename__ = "task"
|
||||||
|
__allow_unmapped__ = True
|
||||||
id: int = db.Column(db.Integer, primary_key=True)
|
id: int = db.Column(db.Integer, primary_key=True)
|
||||||
guid: str = db.Column(db.String(36), nullable=False, unique=True)
|
guid: str = db.Column(db.String(36), nullable=False, unique=True)
|
||||||
bpmn_process_id: int = db.Column(ForeignKey(BpmnProcessModel.id), nullable=False, index=True) # type: ignore
|
bpmn_process_id: int = db.Column(ForeignKey(BpmnProcessModel.id), nullable=False, index=True) # type: ignore
|
||||||
|
|
|
@ -632,9 +632,10 @@ def process_instance_task_list(
|
||||||
status_code=400,
|
status_code=400,
|
||||||
)
|
)
|
||||||
|
|
||||||
_parent_bpmn_processes, task_models_of_parent_bpmn_processes = (
|
(
|
||||||
TaskService.task_models_of_parent_bpmn_processes(to_task_model)
|
_parent_bpmn_processes,
|
||||||
)
|
task_models_of_parent_bpmn_processes,
|
||||||
|
) = TaskService.task_models_of_parent_bpmn_processes(to_task_model)
|
||||||
task_models_of_parent_bpmn_processes_guids = [p.guid for p in task_models_of_parent_bpmn_processes if p.guid]
|
task_models_of_parent_bpmn_processes_guids = [p.guid for p in task_models_of_parent_bpmn_processes if p.guid]
|
||||||
task_model_query = task_model_query.filter(
|
task_model_query = task_model_query.filter(
|
||||||
or_(
|
or_(
|
||||||
|
|
|
@ -43,11 +43,10 @@ from SpiffWorkflow.bpmn.specs.events.EndEvent import EndEvent # type: ignore
|
||||||
from SpiffWorkflow.bpmn.specs.events.StartEvent import StartEvent # type: ignore
|
from SpiffWorkflow.bpmn.specs.events.StartEvent import StartEvent # type: ignore
|
||||||
from SpiffWorkflow.bpmn.specs.SubWorkflowTask import SubWorkflowTask # type: ignore
|
from SpiffWorkflow.bpmn.specs.SubWorkflowTask import SubWorkflowTask # type: ignore
|
||||||
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow # type: ignore
|
from SpiffWorkflow.bpmn.workflow import BpmnWorkflow # type: ignore
|
||||||
from SpiffWorkflow.dmn.parser.BpmnDmnParser import BpmnDmnParser # type: ignore
|
|
||||||
from SpiffWorkflow.dmn.serializer.task_spec import BusinessRuleTaskConverter # type: ignore
|
|
||||||
from SpiffWorkflow.exceptions import WorkflowException # type: ignore
|
from SpiffWorkflow.exceptions import WorkflowException # type: ignore
|
||||||
from SpiffWorkflow.exceptions import WorkflowTaskException
|
from SpiffWorkflow.exceptions import WorkflowTaskException
|
||||||
from SpiffWorkflow.serializer.exceptions import MissingSpecError # type: ignore
|
from SpiffWorkflow.serializer.exceptions import MissingSpecError # type: ignore
|
||||||
|
from SpiffWorkflow.spiff.parser.process import SpiffBpmnParser # type: ignore
|
||||||
from SpiffWorkflow.spiff.serializer.config import SPIFF_SPEC_CONFIG # type: ignore
|
from SpiffWorkflow.spiff.serializer.config import SPIFF_SPEC_CONFIG # type: ignore
|
||||||
from SpiffWorkflow.task import Task as SpiffTask # type: ignore
|
from SpiffWorkflow.task import Task as SpiffTask # type: ignore
|
||||||
from SpiffWorkflow.task import TaskState
|
from SpiffWorkflow.task import TaskState
|
||||||
|
@ -110,8 +109,6 @@ from spiffworkflow_backend.services.workflow_execution_service import (
|
||||||
WorkflowExecutionService,
|
WorkflowExecutionService,
|
||||||
)
|
)
|
||||||
|
|
||||||
SPIFF_SPEC_CONFIG["task_specs"].append(BusinessRuleTaskConverter)
|
|
||||||
|
|
||||||
|
|
||||||
# Sorry about all this crap. I wanted to move this thing to another file, but
|
# Sorry about all this crap. I wanted to move this thing to another file, but
|
||||||
# importing a bunch of types causes circular imports.
|
# importing a bunch of types causes circular imports.
|
||||||
|
@ -1223,13 +1220,16 @@ class ProcessInstanceProcessor:
|
||||||
spiff_tasks_updated[task.id] = task
|
spiff_tasks_updated[task.id] = task
|
||||||
|
|
||||||
for updated_spiff_task in spiff_tasks_updated.values():
|
for updated_spiff_task in spiff_tasks_updated.values():
|
||||||
bpmn_process, task_model, new_task_models, new_json_data_dicts = (
|
(
|
||||||
TaskService.find_or_create_task_model_from_spiff_task(
|
bpmn_process,
|
||||||
updated_spiff_task,
|
task_model,
|
||||||
self.process_instance_model,
|
new_task_models,
|
||||||
self._serializer,
|
new_json_data_dicts,
|
||||||
bpmn_definition_to_task_definitions_mappings=self.bpmn_definition_to_task_definitions_mappings,
|
) = TaskService.find_or_create_task_model_from_spiff_task(
|
||||||
)
|
updated_spiff_task,
|
||||||
|
self.process_instance_model,
|
||||||
|
self._serializer,
|
||||||
|
bpmn_definition_to_task_definitions_mappings=self.bpmn_definition_to_task_definitions_mappings,
|
||||||
)
|
)
|
||||||
bpmn_process_to_use = bpmn_process or task_model.bpmn_process
|
bpmn_process_to_use = bpmn_process or task_model.bpmn_process
|
||||||
bpmn_process_json_data = TaskService.update_task_data_on_bpmn_process(
|
bpmn_process_json_data = TaskService.update_task_data_on_bpmn_process(
|
||||||
|
@ -1439,7 +1439,7 @@ class ProcessInstanceProcessor:
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def update_spiff_parser_with_all_process_dependency_files(
|
def update_spiff_parser_with_all_process_dependency_files(
|
||||||
parser: BpmnDmnParser,
|
parser: SpiffBpmnParser,
|
||||||
processed_identifiers: Optional[set[str]] = None,
|
processed_identifiers: Optional[set[str]] = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Update_spiff_parser_with_all_process_dependency_files."""
|
"""Update_spiff_parser_with_all_process_dependency_files."""
|
||||||
|
|
|
@ -309,11 +309,14 @@ class ProcessInstanceReportService:
|
||||||
) -> list[dict]:
|
) -> list[dict]:
|
||||||
"""Add_metadata_columns_to_process_instance."""
|
"""Add_metadata_columns_to_process_instance."""
|
||||||
results = []
|
results = []
|
||||||
for process_instance in process_instance_sqlalchemy_rows:
|
for process_instance_row in process_instance_sqlalchemy_rows:
|
||||||
process_instance_dict = process_instance["ProcessInstanceModel"].serialized
|
process_instance_mapping = process_instance_row._mapping
|
||||||
|
process_instance_dict = process_instance_row[0].serialized
|
||||||
for metadata_column in metadata_columns:
|
for metadata_column in metadata_columns:
|
||||||
if metadata_column["accessor"] not in process_instance_dict:
|
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_mapping[
|
||||||
|
metadata_column["accessor"]
|
||||||
|
]
|
||||||
|
|
||||||
results.append(process_instance_dict)
|
results.append(process_instance_dict)
|
||||||
return results
|
return results
|
||||||
|
|
|
@ -279,7 +279,8 @@ class ProcessInstanceService:
|
||||||
yield (identifier, list_value, list_index)
|
yield (identifier, list_value, list_index)
|
||||||
if isinstance(list_value, dict) and len(list_value) == 1:
|
if isinstance(list_value, dict) and len(list_value) == 1:
|
||||||
for v in list_value.values():
|
for v in list_value.values():
|
||||||
yield (identifier, v, list_index)
|
if isinstance(v, str):
|
||||||
|
yield (identifier, v, list_index)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def file_data_models_for_data(
|
def file_data_models_for_data(
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import logging
|
|
||||||
import time
|
import time
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
@ -149,13 +148,16 @@ class TaskModelSavingDelegate(EngineStepDelegate):
|
||||||
self.json_data_dicts[json_data_dict["hash"]] = json_data_dict
|
self.json_data_dicts[json_data_dict["hash"]] = json_data_dict
|
||||||
|
|
||||||
def _update_task_model_with_spiff_task(self, spiff_task: SpiffTask, task_failed: bool = False) -> TaskModel:
|
def _update_task_model_with_spiff_task(self, spiff_task: SpiffTask, task_failed: bool = False) -> TaskModel:
|
||||||
bpmn_process, task_model, new_task_models, new_json_data_dicts = (
|
(
|
||||||
TaskService.find_or_create_task_model_from_spiff_task(
|
bpmn_process,
|
||||||
spiff_task,
|
task_model,
|
||||||
self.process_instance,
|
new_task_models,
|
||||||
self.serializer,
|
new_json_data_dicts,
|
||||||
bpmn_definition_to_task_definitions_mappings=self.bpmn_definition_to_task_definitions_mappings,
|
) = TaskService.find_or_create_task_model_from_spiff_task(
|
||||||
)
|
spiff_task,
|
||||||
|
self.process_instance,
|
||||||
|
self.serializer,
|
||||||
|
bpmn_definition_to_task_definitions_mappings=self.bpmn_definition_to_task_definitions_mappings,
|
||||||
)
|
)
|
||||||
bpmn_process_json_data = TaskService.update_task_data_on_bpmn_process(
|
bpmn_process_json_data = TaskService.update_task_data_on_bpmn_process(
|
||||||
bpmn_process or task_model.bpmn_process, spiff_task.workflow.data
|
bpmn_process or task_model.bpmn_process, spiff_task.workflow.data
|
||||||
|
@ -317,10 +319,6 @@ class WorkflowExecutionService:
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
self.execution_strategy.save()
|
self.execution_strategy.save()
|
||||||
spiff_logger = logging.getLogger("spiff")
|
|
||||||
for handler in spiff_logger.handlers:
|
|
||||||
if hasattr(handler, "bulk_insert_logs"):
|
|
||||||
handler.bulk_insert_logs() # type: ignore
|
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
|
|
||||||
if save:
|
if save:
|
||||||
|
|
Loading…
Reference in New Issue