Merge pull request #282 from sartography/feature/ruff-isort

iterating on ruff configs
This commit is contained in:
Kevin Burnett 2023-05-29 16:00:11 +00:00 committed by GitHub
commit 96b516ee55
173 changed files with 2844 additions and 3768 deletions

View File

@ -19,7 +19,6 @@ jobs:
- { python: "3.11", os: "ubuntu-latest", session: "safety" } - { 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.11", python: "3.11",
os: "ubuntu-latest", os: "ubuntu-latest",
@ -44,12 +43,6 @@ jobs:
session: "tests", session: "tests",
database: "sqlite", database: "sqlite",
} }
- {
python: "3.9",
os: "ubuntu-latest",
session: "tests",
database: "sqlite",
}
# FIXME: tests cannot pass on windows and we currently cannot debug # FIXME: tests cannot pass on windows and we currently cannot debug
# since none of us have a windows box that can run the python app. # since none of us have a windows box that can run the python app.
# so ignore windows tests until we can get it fixed. # so ignore windows tests until we can get it fixed.

View File

@ -44,30 +44,13 @@ repos:
language: system language: system
types: [text] types: [text]
stages: [commit, push, manual] stages: [commit, push, manual]
- id: flake8 - id: ruff
files: ^spiffworkflow-backend/ files: ^spiffworkflow-backend/
name: flake8 name: ruff
entry: flake8 entry: ruff
language: system language: system
types: [python] types: [python]
require_serial: true require_serial: true
exclude: "/migrations/"
- id: pyupgrade
files: ^spiffworkflow-backend/
name: pyupgrade
description: Automatically upgrade syntax for newer versions.
entry: pyupgrade
language: system
types: [python]
args: [--py37-plus]
- id: reorder-python-imports
files: ^spiffworkflow-backend/
name: Reorder python imports
entry: reorder-python-imports
language: system
types: [python]
args: [--application-directories=spiffworkflow-backend/src]
exclude: "(/migrations/|load_database_models)"
- id: trailing-whitespace - id: trailing-whitespace
files: ^spiffworkflow-backend/ files: ^spiffworkflow-backend/
name: Trim Trailing Whitespace name: Trim Trailing Whitespace

1027
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,7 @@ pre-commit = "^2.20.0"
flake8 = "^4.0.1" flake8 = "^4.0.1"
black = ">=21.10b0" black = ">=21.10b0"
flake8-bandit = "^2.1.2" flake8-bandit = "^2.1.2"
ruff = "^0.0.270"
# 1.7.3 broke us. https://github.com/PyCQA/bandit/issues/841 # 1.7.3 broke us. https://github.com/PyCQA/bandit/issues/841
bandit = "1.7.2" bandit = "1.7.2"

View File

@ -28,27 +28,6 @@ repos:
language: system language: system
types: [text] types: [text]
stages: [commit, push, manual] stages: [commit, push, manual]
- id: flake8
name: flake8
entry: flake8
language: system
types: [python]
require_serial: true
exclude: ^migrations/
- id: pyupgrade
name: pyupgrade
description: Automatically upgrade syntax for newer versions.
entry: pyupgrade
language: system
types: [python]
args: [--py37-plus]
- id: reorder-python-imports
name: Reorder python imports
entry: reorder-python-imports
language: system
types: [python]
args: [--application-directories=src]
exclude: "(^migrations/|load_database_models)"
- id: trailing-whitespace - id: trailing-whitespace
name: Trim Trailing Whitespace name: Trim Trailing Whitespace
entry: trailing-whitespace-fixer entry: trailing-whitespace-fixer

View File

@ -43,7 +43,7 @@ Request features on the `Issue Tracker`_.
How to set up your development environment How to set up your development environment
------------------------------------------ ------------------------------------------
You need Python 3.9+ and the following tools: You need Python 3.10+ and the following tools:
- Poetry_ - Poetry_
- Nox_ - Nox_

View File

@ -48,7 +48,7 @@ Running Locally
Requirements Requirements
------------ ------------
* Python 3.9+ * Python 3.10+
* Poetry * Poetry

View File

@ -1,6 +1,3 @@
#!/usr/bin/env python
# ^ for syntax highlighting
"""Get the bpmn process json for a given process instance id and store it in /tmp."""
import json import json
import os import os
import sys import sys

View File

@ -5,12 +5,8 @@ from spiffworkflow_backend import get_hacked_up_app_for_script
from spiffworkflow_backend.models.db import db from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.user import UserModel from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.services.process_instance_processor import ( from spiffworkflow_backend.services.process_instance_processor import ProcessInstanceProcessor
ProcessInstanceProcessor, from spiffworkflow_backend.services.process_instance_service import ProcessInstanceService
)
from spiffworkflow_backend.services.process_instance_service import (
ProcessInstanceService,
)
def main(): def main():

View File

@ -2,7 +2,6 @@
import time import time
from apscheduler.schedulers.background import BlockingScheduler # type: ignore from apscheduler.schedulers.background import BlockingScheduler # type: ignore
from spiffworkflow_backend import create_app from spiffworkflow_backend import create_app
from spiffworkflow_backend import start_scheduler from spiffworkflow_backend import start_scheduler
from spiffworkflow_backend.helpers.db_helper import try_to_connect from spiffworkflow_backend.helpers.db_helper import try_to_connect

View File

@ -4,14 +4,13 @@ import shutil
import pytest import pytest
from flask.app import Flask from flask.app import Flask
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
from spiffworkflow_backend.models.bpmn_process import BpmnProcessModel from spiffworkflow_backend.models.bpmn_process import BpmnProcessModel
from spiffworkflow_backend.models.db import db from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.user import UserModel from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.services.authorization_service import AuthorizationService from spiffworkflow_backend.services.authorization_service import AuthorizationService
from spiffworkflow_backend.services.process_model_service import ProcessModelService from spiffworkflow_backend.services.process_model_service import ProcessModelService
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
# We need to call this before importing spiffworkflow_backend # We need to call this before importing spiffworkflow_backend
# otherwise typeguard cannot work. hence the noqa: E402 # otherwise typeguard cannot work. hence the noqa: E402

View File

@ -1,7 +1,6 @@
"""Sphinx configuration.""" """Sphinx configuration."""
from datetime import datetime from datetime import datetime
project = "Spiffworkflow Backend" project = "Spiffworkflow Backend"
author = "Sartography" author = "Sartography"
copyright = f"{datetime.now().year}, {author}" copyright = f"{datetime.now().year}, {author}"

View File

@ -1,9 +1,8 @@
import logging import logging
from logging.config import fileConfig from logging.config import fileConfig
from flask import current_app
from alembic import context from alembic import context
from flask import current_app
# this is the Alembic Config object, which provides # this is the Alembic Config object, which provides
# access to the values within the .ini file in use. # access to the values within the .ini file in use.

View File

@ -5,8 +5,8 @@ Revises:
Create Date: 2023-04-20 14:05:44.779453 Create Date: 2023-04-20 14:05:44.779453
""" """
from alembic import op
import sqlalchemy as sa import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import mysql from sqlalchemy.dialects import mysql
# revision identifiers, used by Alembic. # revision identifiers, used by Alembic.

View File

@ -5,9 +5,8 @@ Revises: 0c7428378d6e
Create Date: 2023-04-27 13:32:04.143969 Create Date: 2023-04-27 13:32:04.143969
""" """
from alembic import op
import sqlalchemy as sa import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic. # revision identifiers, used by Alembic.
revision = '664bb2f00694' revision = '664bb2f00694'

View File

@ -5,9 +5,8 @@ Revises: 0c7428378d6e
Create Date: 2023-04-27 12:24:01.771698 Create Date: 2023-04-27 12:24:01.771698
""" """
from alembic import op
import sqlalchemy as sa import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic. # revision identifiers, used by Alembic.
revision = '68adb1d504e1' revision = '68adb1d504e1'

View File

@ -5,9 +5,8 @@ Revises: 68adb1d504e1
Create Date: 2023-05-04 12:50:07.979692 Create Date: 2023-05-04 12:50:07.979692
""" """
from alembic import op
import sqlalchemy as sa import sqlalchemy as sa
from alembic import op
# revision identifiers, used by Alembic. # revision identifiers, used by Alembic.
revision = '6aa02463da9c' revision = '6aa02463da9c'

View File

@ -21,7 +21,7 @@ except ImportError:
package = "spiffworkflow_backend" package = "spiffworkflow_backend"
python_versions = ["3.11", "3.10", "3.9"] python_versions = ["3.11", "3.10"]
nox.needs_version = ">= 2021.6.6" nox.needs_version = ">= 2021.6.6"
nox.options.sessions = ( nox.options.sessions = (
"pre-commit", "pre-commit",

File diff suppressed because it is too large Load Diff

View File

@ -16,16 +16,18 @@ classifiers = [
Changelog = "https://github.com/sartography/spiffworkflow-backend/releases" Changelog = "https://github.com/sartography/spiffworkflow-backend/releases"
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = ">=3.9,<3.12" python = ">=3.10,<3.12"
click = "^8.0.1" click = "^8.0.1"
flask = "2.2.2" flask = "2.2.2"
flask-admin = "*" flask-admin = "*"
flask-bcrypt = "*" flask-bcrypt = "*"
flask-cors = "*" flask-cors = "*"
flask-jwt-extended = "^4.4.4"
flask-mail = "*" flask-mail = "*"
flask-marshmallow = "*" flask-marshmallow = "*"
flask-migrate = "*" flask-migrate = "*"
flask-restful = "*" flask-restful = "*"
flask-simple-crypt = "^0.3.3"
werkzeug = "*" werkzeug = "*"
SpiffWorkflow = {git = "https://github.com/sartography/SpiffWorkflow", rev = "main"} SpiffWorkflow = {git = "https://github.com/sartography/SpiffWorkflow", rev = "main"}
# SpiffWorkflow = {git = "https://github.com/sartography/SpiffWorkflow", rev = "6cad2981712bb61eca23af1adfafce02d3277cb9"} # SpiffWorkflow = {git = "https://github.com/sartography/SpiffWorkflow", rev = "6cad2981712bb61eca23af1adfafce02d3277cb9"}
@ -58,6 +60,7 @@ Flask-SQLAlchemy = "^3"
# these need to be in the normal (non dev-dependencies) section # 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 # because if not then poetry export won't have them and nox -s mypy --pythons 3.10
# will fail # will fail
types-dateparser = "^1.1.4.1"
types-Werkzeug = "^1.0.9" types-Werkzeug = "^1.0.9"
types-PyYAML = "^6.0.12" types-PyYAML = "^6.0.12"
types-Flask = "^1.1.6" types-Flask = "^1.1.6"
@ -74,14 +77,9 @@ sqlalchemy-stubs = { git = "https://github.com/burnettk/sqlalchemy-stubs.git", r
simplejson = "^3.17.6" simplejson = "^3.17.6"
pytz = "^2022.6" pytz = "^2022.6"
dateparser = "^1.1.2" dateparser = "^1.1.2"
types-dateparser = "^1.1.4.1"
flask-jwt-extended = "^4.4.4"
pylint = "^2.15.10"
flask-simple-crypt = "^0.3.3"
cryptography = "^39.0.2" cryptography = "^39.0.2"
prometheus-flask-exporter = "^0.22.3" prometheus-flask-exporter = "^0.22.3"
safety = "^2.3.5"
sqlalchemy = "^2.0.7" sqlalchemy = "^2.0.7"
marshmallow-sqlalchemy = "^0.29.0" marshmallow-sqlalchemy = "^0.29.0"
spiff-element-units = "^0.3.0" spiff-element-units = "^0.3.0"
@ -89,32 +87,20 @@ spiff-element-units = "^0.3.0"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
pytest = "^7.1.2" pytest = "^7.1.2"
coverage = {extras = ["toml"], version = "^6.1"} coverage = {extras = ["toml"], version = "^6.1"}
safety = "^2.3.1" safety = "^2.3.5"
mypy = ">=0.961" mypy = ">=0.961"
typeguard = "^3" typeguard = "^3"
xdoctest = {extras = ["colors"], version = "^1.0.1"} 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"
black = ">=21.10b0" black = ">=21.10b0"
flake8-bandit = "^2.1.2" ruff = "^0.0.270"
# 1.7.3 broke us. https://github.com/PyCQA/bandit/issues/841 # 1.7.3 broke us. https://github.com/PyCQA/bandit/issues/841
bandit = "1.7.2" bandit = "1.7.2"
flake8-bugbear = "^22.10.25"
flake8-docstrings = "^1.6.0"
flake8-rst-docstrings = "^0.2.7"
# flask-sqlalchemy-stubs = "^0.2" # flask-sqlalchemy-stubs = "^0.2"
pep8-naming = "^0.13.2"
darglint = "^1.8.1"
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" Pygments = "^2.10.0"
pyupgrade = "^3.1.0"
# furo = ">=2021.11.12"
[tool.poetry.scripts] [tool.poetry.scripts]
spiffworkflow-backend = "spiffworkflow_backend.__main__:main" spiffworkflow-backend = "spiffworkflow_backend.__main__:main"
@ -170,12 +156,39 @@ implicit_reexport = true
namespace_packages = true namespace_packages = true
explicit_package_bases = false explicit_package_bases = false
# [tool.pyright]
# Pyright: Import "flask" could not be resolved
# ultimately resolved by creating a pyrightconfig.json file with venv and venvPath
# Pyright: "hey" is not accessed
# See: https://github.com/microsoft/pyright/discussions/3929#discussioncomment-5434231
# "Those are not warnings" and cannot be turned off like this:
# reportUnusedVariable = false
# solution was https://www.reddit.com/r/neovim/comments/11k5but/comment/jbjwwtf in vim settings
[tool.ruff] [tool.ruff]
select = [
"B", # flake8-bugbear
"E", # pycodestyle error
# "ERA", # eradicate
"F", # pyflakes
# "N", # pep8-naming
# "PL", # pylint
# "S", # flake8-bandit
"UP", # pyupgrade
"W", # pycodestyle warning
"I001" # isort
]
line-length = 130 line-length = 130
# target python 3.10
target-version = "py310"
[tool.ruff.per-file-ignores] [tool.ruff.per-file-ignores]
"migrations/versions/*.py" = ["E501"] "migrations/versions/*.py" = ["E501"]
[tool.ruff.isort]
force-single-line = true
[build-system] [build-system]
requires = ["poetry-core>=1.0.0"] requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api" build-backend = "poetry.core.masonry.api"

View File

@ -1,7 +1,7 @@
sonar.organization=sartography sonar.organization=sartography
sonar.projectKey=sartography_spiffworkflow-backend sonar.projectKey=sartography_spiffworkflow-backend
sonar.host.url=https://sonarcloud.io sonar.host.url=https://sonarcloud.io
sonar.python.version=3.9,3.10,3.11 sonar.python.version=3.10,3.11
sonar.python.coverage.reportPaths=coverage.xml sonar.python.coverage.reportPaths=coverage.xml
sonar.test.inclusions=tests sonar.test.inclusions=tests

View File

@ -25,16 +25,12 @@ from spiffworkflow_backend.exceptions.api_error import api_error_blueprint
from spiffworkflow_backend.helpers.api_version import V1_API_PATH_PREFIX from spiffworkflow_backend.helpers.api_version import V1_API_PATH_PREFIX
from spiffworkflow_backend.models.db import db from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import migrate from spiffworkflow_backend.models.db import migrate
from spiffworkflow_backend.routes.openid_blueprint.openid_blueprint import ( from spiffworkflow_backend.routes.openid_blueprint.openid_blueprint import openid_blueprint
openid_blueprint,
)
from spiffworkflow_backend.routes.user import set_new_access_token_in_cookie from spiffworkflow_backend.routes.user import set_new_access_token_in_cookie
from spiffworkflow_backend.routes.user import verify_token from spiffworkflow_backend.routes.user import verify_token
from spiffworkflow_backend.routes.user_blueprint import user_blueprint from spiffworkflow_backend.routes.user_blueprint import user_blueprint
from spiffworkflow_backend.services.authorization_service import AuthorizationService from spiffworkflow_backend.services.authorization_service import AuthorizationService
from spiffworkflow_backend.services.background_processing_service import ( from spiffworkflow_backend.services.background_processing_service import BackgroundProcessingService
BackgroundProcessingService,
)
class MyJSONEncoder(DefaultJSONProvider): class MyJSONEncoder(DefaultJSONProvider):

View File

@ -20,7 +20,6 @@ from SpiffWorkflow.exceptions import SpiffWorkflowException # type: ignore
from SpiffWorkflow.exceptions import WorkflowException from SpiffWorkflow.exceptions import WorkflowException
from SpiffWorkflow.specs.base import TaskSpec # type: ignore from SpiffWorkflow.specs.base import TaskSpec # type: ignore
from SpiffWorkflow.task import Task # type: ignore from SpiffWorkflow.task import Task # type: ignore
from spiffworkflow_backend.models.task import TaskModel # noqa: F401 from spiffworkflow_backend.models.task import TaskModel # noqa: F401
from spiffworkflow_backend.services.authentication_service import NotAuthorizedError from spiffworkflow_backend.services.authentication_service import NotAuthorizedError
from spiffworkflow_backend.services.authentication_service import TokenInvalidError from spiffworkflow_backend.services.authentication_service import TokenInvalidError
@ -29,7 +28,6 @@ from spiffworkflow_backend.services.authentication_service import UserNotLoggedI
from spiffworkflow_backend.services.task_service import TaskModelError from spiffworkflow_backend.services.task_service import TaskModelError
from spiffworkflow_backend.services.task_service import TaskService from spiffworkflow_backend.services.task_service import TaskService
api_error_blueprint = Blueprint("api_error_blueprint", __name__) api_error_blueprint = Blueprint("api_error_blueprint", __name__)

View File

@ -2,9 +2,8 @@
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
from sqlalchemy.sql import text
def try_to_connect(start_time: float) -> None: def try_to_connect(start_time: float) -> None:

View File

@ -1,6 +1,6 @@
"""Interfaces.""" """Interfaces."""
from typing import NewType
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from typing import NewType
from typing import TypedDict from typing import TypedDict
if TYPE_CHECKING: if TYPE_CHECKING:

View File

@ -10,6 +10,9 @@ avoid circular imports
# unused imports are needed for SQLAlchemy to load the models # unused imports are needed for SQLAlchemy to load the models
# ruff: noqa: F401 # ruff: noqa: F401
# we do not want to sort imports in this file, since the order matters
# ruff: noqa: I001
from spiffworkflow_backend.models.db import add_listeners from spiffworkflow_backend.models.db import add_listeners
# must load these before UserModel and GroupModel for relationships # must load these before UserModel and GroupModel for relationships

View File

@ -2,8 +2,8 @@ from __future__ import annotations
from sqlalchemy import ForeignKey from sqlalchemy import ForeignKey
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.user import UserModel from spiffworkflow_backend.models.user import UserModel

View File

@ -6,8 +6,8 @@ from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from spiffworkflow_backend.models.bpmn_process_definition import BpmnProcessDefinitionModel from spiffworkflow_backend.models.bpmn_process_definition import BpmnProcessDefinitionModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
class BpmnProcessNotFoundError(Exception): class BpmnProcessNotFoundError(Exception):

View File

@ -4,8 +4,8 @@ from dataclasses import dataclass
from sqlalchemy import UniqueConstraint from sqlalchemy import UniqueConstraint
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
# contents of top-level attributes from spiff: # contents of top-level attributes from spiff:

View File

@ -5,11 +5,9 @@ from dataclasses import dataclass
from sqlalchemy import ForeignKey from sqlalchemy import ForeignKey
from sqlalchemy import UniqueConstraint from sqlalchemy import UniqueConstraint
from spiffworkflow_backend.models.bpmn_process_definition import ( from spiffworkflow_backend.models.bpmn_process_definition import BpmnProcessDefinitionModel
BpmnProcessDefinitionModel,
)
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
@dataclass @dataclass

View File

@ -1,8 +1,8 @@
"""Message_correlation.""" """Message_correlation."""
from dataclasses import dataclass from dataclasses import dataclass
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
@dataclass @dataclass

View File

@ -5,14 +5,13 @@ from typing import TYPE_CHECKING
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
if TYPE_CHECKING: if TYPE_CHECKING:
from spiffworkflow_backend.models.user_group_assignment import ( # noqa: F401 # noqa: F401
UserGroupAssignmentModel,
) # noqa: F401
from spiffworkflow_backend.models.user import UserModel # noqa: F401 from spiffworkflow_backend.models.user import UserModel # noqa: F401
from spiffworkflow_backend.models.user_group_assignment import UserGroupAssignmentModel # noqa: F401
SPIFF_NO_AUTH_ANONYMOUS_GROUP = "spiff_anonymous_group" SPIFF_NO_AUTH_ANONYMOUS_GROUP = "spiff_anonymous_group"

View File

@ -8,19 +8,16 @@ from flask import g
from sqlalchemy import ForeignKey from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.group import GroupModel from spiffworkflow_backend.models.group import GroupModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.task import Task from spiffworkflow_backend.models.task import Task
from spiffworkflow_backend.models.task import TaskModel from spiffworkflow_backend.models.task import TaskModel
from spiffworkflow_backend.models.user import UserModel from spiffworkflow_backend.models.user import UserModel
if TYPE_CHECKING: if TYPE_CHECKING:
from spiffworkflow_backend.models.human_task_user import ( # noqa: F401 from spiffworkflow_backend.models.human_task_user import HumanTaskUserModel # noqa: F401
HumanTaskUserModel,
)
@dataclass @dataclass

View File

@ -6,8 +6,8 @@ from dataclasses import dataclass
from sqlalchemy import ForeignKey from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.human_task import HumanTaskModel from spiffworkflow_backend.models.human_task import HumanTaskModel
from spiffworkflow_backend.models.user import UserModel from spiffworkflow_backend.models.user import UserModel

View File

@ -8,8 +8,8 @@ from flask import current_app
from sqlalchemy.dialects.mysql import insert as mysql_insert from sqlalchemy.dialects.mysql import insert as mysql_insert
from sqlalchemy.dialects.postgresql import insert as postgres_insert from sqlalchemy.dialects.postgresql import insert as postgres_insert
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
class JsonDataModelNotFoundError(Exception): class JsonDataModelNotFoundError(Exception):

View File

@ -1,25 +1,24 @@
"""Message_instance.""" """Message_instance."""
import enum import enum
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any
from typing import Optional
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from typing import Any
from flask import current_app from flask import current_app
from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine # type: ignore from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine # type: ignore
from sqlalchemy import ForeignKey from sqlalchemy import ForeignKey
from sqlalchemy.event import listens_for from sqlalchemy.event import listens_for
from sqlalchemy.orm import relationship
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from sqlalchemy.orm import relationship
from sqlalchemy.orm import validates from sqlalchemy.orm import validates
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.user import UserModel from spiffworkflow_backend.models.user import UserModel
if TYPE_CHECKING: if TYPE_CHECKING:
from spiffworkflow_backend.models.message_instance_correlation import ( # noqa: F401 from spiffworkflow_backend.models.message_instance_correlation import ( # noqa: F401,I001
MessageInstanceCorrelationRuleModel, MessageInstanceCorrelationRuleModel,
) )
@ -151,7 +150,7 @@ class MessageInstanceModel(SpiffworkflowBaseDBModel):
@listens_for(Session, "before_flush") # type: ignore @listens_for(Session, "before_flush") # type: ignore
def ensure_failure_cause_is_set_if_message_instance_failed( def ensure_failure_cause_is_set_if_message_instance_failed(
session: Any, _flush_context: Optional[Any], _instances: Optional[Any] session: Any, _flush_context: Any | None, _instances: Any | None
) -> None: ) -> None:
"""Ensure_failure_cause_is_set_if_message_instance_failed.""" """Ensure_failure_cause_is_set_if_message_instance_failed."""
for instance in session.new: for instance in session.new:

View File

@ -4,8 +4,8 @@ from dataclasses import dataclass
from sqlalchemy import ForeignKey from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.message_instance import MessageInstanceModel from spiffworkflow_backend.models.message_instance import MessageInstanceModel

View File

@ -1,6 +1,6 @@
"""Message_correlation_property.""" """Message_correlation_property."""
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
class MessageTriggerableProcessModel(SpiffworkflowBaseDBModel): class MessageTriggerableProcessModel(SpiffworkflowBaseDBModel):

View File

@ -5,8 +5,8 @@ from typing import Any
from sqlalchemy import ForeignKey from sqlalchemy import ForeignKey
from sqlalchemy.orm import validates from sqlalchemy.orm import validates
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.permission_target import PermissionTargetModel from spiffworkflow_backend.models.permission_target import PermissionTargetModel
from spiffworkflow_backend.models.principal import PrincipalModel from spiffworkflow_backend.models.principal import PrincipalModel

View File

@ -1,12 +1,11 @@
"""PermissionTarget.""" """PermissionTarget."""
import re import re
from dataclasses import dataclass from dataclasses import dataclass
from typing import Optional
from sqlalchemy.orm import validates from sqlalchemy.orm import validates
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
class InvalidPermissionTargetUriError(Exception): class InvalidPermissionTargetUriError(Exception):
@ -24,7 +23,7 @@ class PermissionTargetModel(SpiffworkflowBaseDBModel):
id: int = db.Column(db.Integer, primary_key=True) id: int = db.Column(db.Integer, primary_key=True)
uri: str = db.Column(db.String(255), unique=True, nullable=False) uri: str = db.Column(db.String(255), unique=True, nullable=False)
def __init__(self, uri: str, id: Optional[int] = None): def __init__(self, uri: str, id: int | None = None):
"""__init__.""" """__init__."""
if id: if id:
self.id = id self.id = id

View File

@ -5,8 +5,8 @@ from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from sqlalchemy.schema import CheckConstraint from sqlalchemy.schema import CheckConstraint
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.group import GroupModel from spiffworkflow_backend.models.group import GroupModel
from spiffworkflow_backend.models.user import UserModel from spiffworkflow_backend.models.user import UserModel

View File

@ -1,6 +1,6 @@
"""ProcessCaller_model.""" """ProcessCaller_model."""
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
class ProcessCallerCacheModel(SpiffworkflowBaseDBModel): class ProcessCallerCacheModel(SpiffworkflowBaseDBModel):

View File

@ -8,8 +8,8 @@ from dataclasses import field
from typing import Any from typing import Any
import marshmallow import marshmallow
from marshmallow import post_load
from marshmallow import Schema from marshmallow import Schema
from marshmallow import post_load
from spiffworkflow_backend.interfaces import ProcessGroupLite from spiffworkflow_backend.interfaces import ProcessGroupLite
from spiffworkflow_backend.models.process_model import ProcessModelInfo from spiffworkflow_backend.models.process_model import ProcessModelInfo

View File

@ -15,11 +15,9 @@ from sqlalchemy.orm import validates
from spiffworkflow_backend.helpers.spiff_enum import SpiffEnum from spiffworkflow_backend.helpers.spiff_enum import SpiffEnum
from spiffworkflow_backend.models.bpmn_process import BpmnProcessModel from spiffworkflow_backend.models.bpmn_process import BpmnProcessModel
from spiffworkflow_backend.models.bpmn_process_definition import ( from spiffworkflow_backend.models.bpmn_process_definition import BpmnProcessDefinitionModel
BpmnProcessDefinitionModel,
)
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.task import Task from spiffworkflow_backend.models.task import Task
from spiffworkflow_backend.models.task import TaskSchema from spiffworkflow_backend.models.task import TaskSchema
from spiffworkflow_backend.models.user import UserModel from spiffworkflow_backend.models.user import UserModel

View File

@ -1,11 +1,10 @@
from dataclasses import dataclass from dataclasses import dataclass
from typing import Optional
from sqlalchemy import ForeignKey from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
@dataclass @dataclass
@ -19,9 +18,9 @@ class ProcessInstanceErrorDetailModel(SpiffworkflowBaseDBModel):
message: str = db.Column(db.String(1024), nullable=False) message: str = db.Column(db.String(1024), nullable=False)
# this should be 65k in mysql # this should be 65k in mysql
stacktrace: Optional[list] = db.Column(db.JSON, nullable=False) stacktrace: list | None = db.Column(db.JSON, nullable=False)
task_line_number: Optional[int] = db.Column(db.Integer) task_line_number: int | None = db.Column(db.Integer)
task_offset: Optional[int] = db.Column(db.Integer) task_offset: int | None = db.Column(db.Integer)
task_line_contents: Optional[str] = db.Column(db.String(255)) task_line_contents: str | None = db.Column(db.String(255))
task_trace: Optional[list] = db.Column(db.JSON) task_trace: list | None = db.Column(db.JSON)

View File

@ -7,8 +7,8 @@ from sqlalchemy.orm import relationship
from sqlalchemy.orm import validates from sqlalchemy.orm import validates
from spiffworkflow_backend.helpers.spiff_enum import SpiffEnum 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.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.user import UserModel from spiffworkflow_backend.models.user import UserModel

View File

@ -1,12 +1,11 @@
"""Process_instance_file_data.""" """Process_instance_file_data."""
from dataclasses import dataclass from dataclasses import dataclass
from typing import Optional
from sqlalchemy import ForeignKey from sqlalchemy import ForeignKey
from sqlalchemy.dialects.mysql import LONGBLOB from sqlalchemy.dialects.mysql import LONGBLOB
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
@ -19,7 +18,7 @@ class ProcessInstanceFileDataModel(SpiffworkflowBaseDBModel):
ForeignKey(ProcessInstanceModel.id), nullable=False, index=True # type: ignore ForeignKey(ProcessInstanceModel.id), nullable=False, index=True # type: ignore
) )
identifier: str = db.Column(db.String(255), nullable=False) identifier: str = db.Column(db.String(255), nullable=False)
list_index: Optional[int] = db.Column(db.Integer, nullable=True) list_index: int | None = db.Column(db.Integer, nullable=True)
mimetype: str = db.Column(db.String(255), nullable=False) mimetype: str = db.Column(db.String(255), nullable=False)
filename: str = db.Column(db.String(255), nullable=False) filename: str = db.Column(db.String(255), nullable=False)
# this is not deferred because there is no reason to query this model if you do not want the contents # this is not deferred because there is no reason to query this model if you do not want the contents

View File

@ -2,8 +2,8 @@ from dataclasses import dataclass
from sqlalchemy import ForeignKey from sqlalchemy import ForeignKey
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel from spiffworkflow_backend.models.process_instance import ProcessInstanceModel

View File

@ -1,11 +1,10 @@
"""Process_instance_queue.""" """Process_instance_queue."""
from dataclasses import dataclass from dataclasses import dataclass
from typing import Union
from sqlalchemy import ForeignKey from sqlalchemy import ForeignKey
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
@ -21,8 +20,8 @@ class ProcessInstanceQueueModel(SpiffworkflowBaseDBModel):
) )
run_at_in_seconds: int = db.Column(db.Integer) run_at_in_seconds: int = db.Column(db.Integer)
priority: int = db.Column(db.Integer) priority: int = db.Column(db.Integer)
locked_by: Union[str, None] = db.Column(db.String(80), index=True, nullable=True) locked_by: str | None = db.Column(db.String(80), index=True, nullable=True)
locked_at_in_seconds: Union[int, None] = db.Column(db.Integer, index=True, nullable=True) locked_at_in_seconds: int | None = db.Column(db.Integer, index=True, nullable=True)
status: str = db.Column(db.String(50), index=True) status: str = db.Column(db.String(50), index=True)
updated_at_in_seconds: int = db.Column(db.Integer) updated_at_in_seconds: int = db.Column(db.Integer)
created_at_in_seconds: int = db.Column(db.Integer) created_at_in_seconds: int = db.Column(db.Integer)

View File

@ -7,15 +7,17 @@ from dataclasses import dataclass
from typing import Any from typing import Any
if sys.version_info < (3, 11): if sys.version_info < (3, 11):
from typing_extensions import TypedDict, NotRequired from typing_extensions import NotRequired
from typing_extensions import TypedDict
else: else:
from typing import TypedDict, NotRequired from typing import NotRequired
from typing import TypedDict
from sqlalchemy import ForeignKey from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.json_data import JsonDataModel # noqa: F401 from spiffworkflow_backend.models.json_data import JsonDataModel # noqa: F401
from spiffworkflow_backend.models.user import UserModel from spiffworkflow_backend.models.user import UserModel
@ -123,7 +125,7 @@ class ProcessInstanceReportModel(SpiffworkflowBaseDBModel):
f"Process instance report with identifier already exists: {identifier}" f"Process instance report with identifier already exists: {identifier}"
) )
report_metadata_dict = typing.cast(typing.Dict[str, Any], report_metadata) report_metadata_dict = typing.cast(dict[str, Any], report_metadata)
json_data_hash = JsonDataModel.create_and_insert_json_data_from_dict(report_metadata_dict) json_data_hash = JsonDataModel.create_and_insert_json_data_from_dict(report_metadata_dict)
process_instance_report = cls( process_instance_report = cls(

View File

@ -3,8 +3,8 @@ from dataclasses import dataclass
from sqlalchemy import ForeignKey from sqlalchemy import ForeignKey
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
# from sqlalchemy.orm import relationship # from sqlalchemy.orm import relationship

View File

@ -1,12 +1,11 @@
from dataclasses import dataclass from dataclasses import dataclass
from typing import Optional
from SpiffWorkflow.task import Task as SpiffTask # type: ignore from SpiffWorkflow.task import Task as SpiffTask # type: ignore
@dataclass @dataclass
class ScriptAttributesContext: class ScriptAttributesContext:
task: Optional[SpiffTask] task: SpiffTask | None
environment_identifier: str environment_identifier: str
process_instance_id: Optional[int] process_instance_id: int | None
process_model_identifier: Optional[str] process_model_identifier: str | None

View File

@ -4,8 +4,8 @@ from dataclasses import dataclass
from marshmallow import Schema from marshmallow import Schema
from sqlalchemy import ForeignKey from sqlalchemy import ForeignKey
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.user import UserModel from spiffworkflow_backend.models.user import UserModel

View File

@ -5,8 +5,8 @@ from flask_marshmallow import Schema # type: ignore
from marshmallow import INCLUDE from marshmallow import INCLUDE
from sqlalchemy import UniqueConstraint from sqlalchemy import UniqueConstraint
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
class SpecReferenceNotFoundError(Exception): class SpecReferenceNotFoundError(Exception):

View File

@ -1,11 +1,8 @@
"""Task.""" """Task."""
import enum import enum
from dataclasses import dataclass from dataclasses import dataclass
from typing import Any
from typing import List
from typing import Optional
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from typing import Union from typing import Any
import marshmallow import marshmallow
from marshmallow import Schema from marshmallow import Schema
@ -15,15 +12,13 @@ from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from spiffworkflow_backend.models.bpmn_process import BpmnProcessModel from spiffworkflow_backend.models.bpmn_process import BpmnProcessModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.json_data import JsonDataModel from spiffworkflow_backend.models.json_data import JsonDataModel
from spiffworkflow_backend.models.task_definition import TaskDefinitionModel from spiffworkflow_backend.models.task_definition import TaskDefinitionModel
if TYPE_CHECKING: if TYPE_CHECKING:
from spiffworkflow_backend.models.human_task_user import ( # noqa: F401 from spiffworkflow_backend.models.human_task_user import HumanTaskModel # noqa: F401
HumanTaskModel,
)
class TaskNotFoundError(Exception): class TaskNotFoundError(Exception):
@ -72,21 +67,21 @@ class TaskModel(SpiffworkflowBaseDBModel):
json_data_hash: str = db.Column(db.String(255), nullable=False, index=True) json_data_hash: str = db.Column(db.String(255), nullable=False, index=True)
python_env_data_hash: str = db.Column(db.String(255), nullable=False, index=True) python_env_data_hash: str = db.Column(db.String(255), nullable=False, index=True)
start_in_seconds: Union[float, None] = db.Column(db.DECIMAL(17, 6)) start_in_seconds: float | None = db.Column(db.DECIMAL(17, 6))
end_in_seconds: Union[float, None] = db.Column(db.DECIMAL(17, 6)) end_in_seconds: float | None = db.Column(db.DECIMAL(17, 6))
data: Optional[dict] = None data: dict | None = None
# these are here to be compatible with task api # these are here to be compatible with task api
form_schema: Optional[dict] = None form_schema: dict | None = None
form_ui_schema: Optional[dict] = None form_ui_schema: dict | None = None
process_model_display_name: Optional[str] = None process_model_display_name: str | None = None
process_model_identifier: Optional[str] = None process_model_identifier: str | None = None
typename: Optional[str] = None typename: str | None = None
can_complete: Optional[bool] = None can_complete: bool | None = None
extensions: Optional[dict] = None extensions: dict | None = None
name_for_display: Optional[str] = None name_for_display: str | None = None
signal_buttons: Optional[List[dict]] = None signal_buttons: list[dict] | None = None
def get_data(self) -> dict: def get_data(self) -> dict:
return {**self.python_env_data(), **self.json_data()} return {**self.python_env_data(), **self.json_data()}
@ -111,28 +106,28 @@ class Task:
type: str, type: str,
state: str, state: str,
can_complete: bool, can_complete: bool,
lane: Union[str, None] = None, lane: str | None = None,
form: None = None, form: None = None,
documentation: str = "", documentation: str = "",
data: Union[dict[str, Any], None] = None, data: dict[str, Any] | None = None,
multi_instance_type: Union[MultiInstanceType, None] = None, multi_instance_type: MultiInstanceType | None = None,
multi_instance_count: str = "", multi_instance_count: str = "",
multi_instance_index: str = "", multi_instance_index: str = "",
process_identifier: str = "", process_identifier: str = "",
properties: Union[dict, None] = None, properties: dict | None = None,
process_instance_id: Union[int, None] = None, process_instance_id: int | None = None,
process_instance_status: Union[str, None] = None, process_instance_status: str | None = None,
process_model_display_name: Union[str, None] = None, process_model_display_name: str | None = None,
process_group_identifier: Union[str, None] = None, process_group_identifier: str | None = None,
process_model_identifier: Union[str, None] = None, process_model_identifier: str | None = None,
bpmn_process_identifier: Union[str, None] = None, bpmn_process_identifier: str | None = None,
form_schema: Union[dict, None] = None, form_schema: dict | None = None,
form_ui_schema: Union[dict, None] = None, form_ui_schema: dict | None = None,
parent: Optional[str] = None, parent: str | None = None,
event_definition: Union[dict[str, Any], None] = None, event_definition: dict[str, Any] | None = None,
call_activity_process_identifier: Optional[str] = None, call_activity_process_identifier: str | None = None,
calling_subprocess_task_id: Optional[str] = None, calling_subprocess_task_id: str | None = None,
error_message: Optional[str] = None, error_message: str | None = None,
): ):
"""__init__.""" """__init__."""
self.id = id self.id = id

View File

@ -6,11 +6,9 @@ from sqlalchemy import ForeignKey
from sqlalchemy import UniqueConstraint from sqlalchemy import UniqueConstraint
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from spiffworkflow_backend.models.bpmn_process_definition import ( from spiffworkflow_backend.models.bpmn_process_definition import BpmnProcessDefinitionModel
BpmnProcessDefinitionModel,
)
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
@dataclass @dataclass

View File

@ -10,11 +10,10 @@ from flask import current_app
from marshmallow import Schema from marshmallow import Schema
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.group import GroupModel from spiffworkflow_backend.models.group import GroupModel
SPIFF_NO_AUTH_ANONYMOUS_USER = "spiff_anonymous_user" SPIFF_NO_AUTH_ANONYMOUS_USER = "spiff_anonymous_user"

View File

@ -2,8 +2,8 @@
from sqlalchemy import ForeignKey from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.group import GroupModel from spiffworkflow_backend.models.group import GroupModel
from spiffworkflow_backend.models.user import UserModel from spiffworkflow_backend.models.user import UserModel

View File

@ -2,8 +2,8 @@
from sqlalchemy import ForeignKey from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship from sqlalchemy.orm import relationship
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.group import GroupModel from spiffworkflow_backend.models.group import GroupModel

View File

@ -1,8 +1,6 @@
"""APIs for dealing with process groups, process models, and process instances.""" """APIs for dealing with process groups, process models, and process instances."""
import json import json
from typing import Any from typing import Any
from typing import Dict
from typing import Optional
import flask.wrappers import flask.wrappers
from flask import g from flask import g
@ -19,7 +17,7 @@ from spiffworkflow_backend.services.message_service import MessageService
def message_instance_list( def message_instance_list(
process_instance_id: Optional[int] = None, process_instance_id: int | None = None,
page: int = 1, page: int = 1,
per_page: int = 100, per_page: int = 100,
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
@ -67,7 +65,7 @@ def message_instance_list(
# --data-raw '{"payload":{"sure": "yes", "food": "spicy"}}' # --data-raw '{"payload":{"sure": "yes", "food": "spicy"}}'
def message_send( def message_send(
message_name: str, message_name: str,
body: Dict[str, Any], body: dict[str, Any],
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
if "payload" not in body: if "payload" not in body:
raise ( raise (

View File

@ -1,7 +1,6 @@
"""APIs for dealing with process groups, process models, and process instances.""" """APIs for dealing with process groups, process models, and process instances."""
import json import json
from typing import Any from typing import Any
from typing import Dict
import flask.wrappers import flask.wrappers
from flask import Blueprint from flask import Blueprint
@ -13,14 +12,10 @@ from flask import request
from flask.wrappers import 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 ( from spiffworkflow_backend.exceptions.process_entity_not_found_error import ProcessEntityNotFoundError
ProcessEntityNotFoundError,
)
from spiffworkflow_backend.models.principal import PrincipalModel from spiffworkflow_backend.models.principal import PrincipalModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.process_instance_file_data import ( from spiffworkflow_backend.models.process_instance_file_data import ProcessInstanceFileDataModel
ProcessInstanceFileDataModel,
)
from spiffworkflow_backend.models.process_model import ProcessModelInfo from spiffworkflow_backend.models.process_model import ProcessModelInfo
from spiffworkflow_backend.models.spec_reference import SpecReferenceCache from spiffworkflow_backend.models.spec_reference import SpecReferenceCache
from spiffworkflow_backend.models.spec_reference import SpecReferenceSchema from spiffworkflow_backend.models.spec_reference import SpecReferenceSchema
@ -28,16 +23,13 @@ from spiffworkflow_backend.models.task import TaskModel # noqa: F401
from spiffworkflow_backend.services.authorization_service import AuthorizationService from spiffworkflow_backend.services.authorization_service import AuthorizationService
from spiffworkflow_backend.services.git_service import GitService from spiffworkflow_backend.services.git_service import GitService
from spiffworkflow_backend.services.process_caller_service import ProcessCallerService from spiffworkflow_backend.services.process_caller_service import ProcessCallerService
from spiffworkflow_backend.services.process_instance_processor import ( from spiffworkflow_backend.services.process_instance_processor import ProcessInstanceProcessor
ProcessInstanceProcessor,
)
from spiffworkflow_backend.services.process_model_service import ProcessModelService from spiffworkflow_backend.services.process_model_service import ProcessModelService
process_api_blueprint = Blueprint("process_api", __name__) process_api_blueprint = Blueprint("process_api", __name__)
def permissions_check(body: Dict[str, Dict[str, list[str]]]) -> flask.wrappers.Response: def permissions_check(body: dict[str, dict[str, list[str]]]) -> flask.wrappers.Response:
"""Permissions_check.""" """Permissions_check."""
if "requests_to_check" not in body: if "requests_to_check" not in body:
raise ( raise (
@ -162,7 +154,7 @@ def process_data_file_download(
# "full_name": "sartography/sample-process-models", "private": False .... }} # "full_name": "sartography/sample-process-models", "private": False .... }}
# test with: ngrok http 7000 # test with: ngrok http 7000
# where 7000 is the port the app is running on locally # where 7000 is the port the app is running on locally
def github_webhook_receive(body: Dict) -> Response: def github_webhook_receive(body: dict) -> Response:
"""Github_webhook_receive.""" """Github_webhook_receive."""
auth_header = request.headers.get("X-Hub-Signature-256") auth_header = request.headers.get("X-Hub-Signature-256")
AuthorizationService.verify_sha256_token(auth_header) AuthorizationService.verify_sha256_token(auth_header)

View File

@ -1,7 +1,6 @@
"""APIs for dealing with process groups, process models, and process instances.""" """APIs for dealing with process groups, process models, and process instances."""
import json import json
from typing import Any from typing import Any
from typing import Optional
import flask.wrappers import flask.wrappers
from flask import g from flask import g
@ -10,19 +9,13 @@ from flask import make_response
from flask.wrappers import 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 ( from spiffworkflow_backend.exceptions.process_entity_not_found_error import ProcessEntityNotFoundError
ProcessEntityNotFoundError,
)
from spiffworkflow_backend.models.process_group import ProcessGroup from spiffworkflow_backend.models.process_group import ProcessGroup
from spiffworkflow_backend.models.process_group import ProcessGroupSchema from spiffworkflow_backend.models.process_group import ProcessGroupSchema
from spiffworkflow_backend.routes.process_api_blueprint import _commit_and_push_to_git from spiffworkflow_backend.routes.process_api_blueprint import _commit_and_push_to_git
from spiffworkflow_backend.routes.process_api_blueprint import ( from spiffworkflow_backend.routes.process_api_blueprint import _un_modify_modified_process_model_id
_un_modify_modified_process_model_id,
)
from spiffworkflow_backend.services.process_model_service import ProcessModelService from spiffworkflow_backend.services.process_model_service import ProcessModelService
from spiffworkflow_backend.services.process_model_service import ( from spiffworkflow_backend.services.process_model_service import ProcessModelWithInstancesNotDeletableError
ProcessModelWithInstancesNotDeletableError,
)
def process_group_create(body: dict) -> flask.wrappers.Response: def process_group_create(body: dict) -> flask.wrappers.Response:
@ -85,7 +78,7 @@ def process_group_update(modified_process_group_id: str, body: dict) -> flask.wr
def process_group_list( def process_group_list(
process_group_identifier: Optional[str] = None, page: int = 1, per_page: int = 100 process_group_identifier: str | None = None, page: int = 1, per_page: int = 100
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
process_groups = ProcessModelService.get_process_groups_for_api(process_group_identifier) process_groups = ProcessModelService.get_process_groups_for_api(process_group_identifier)
batch = ProcessModelService.get_batch(items=process_groups, page=page, per_page=per_page) batch = ProcessModelService.get_batch(items=process_groups, page=page, per_page=per_page)

View File

@ -1,6 +1,3 @@
from typing import Optional
from typing import Set
import flask.wrappers import flask.wrappers
from flask import jsonify from flask import jsonify
from flask import make_response from flask import make_response
@ -14,9 +11,7 @@ from spiffworkflow_backend.models.process_instance_event import ProcessInstanceE
from spiffworkflow_backend.models.task import TaskModel # noqa: F401 from spiffworkflow_backend.models.task import TaskModel # noqa: F401
from spiffworkflow_backend.models.task_definition import TaskDefinitionModel from spiffworkflow_backend.models.task_definition import TaskDefinitionModel
from spiffworkflow_backend.models.user import UserModel from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.routes.process_api_blueprint import ( from spiffworkflow_backend.routes.process_api_blueprint import _find_process_instance_by_id_or_raise
_find_process_instance_by_id_or_raise,
)
def log_list( def log_list(
@ -25,10 +20,10 @@ def log_list(
page: int = 1, page: int = 1,
per_page: int = 100, per_page: int = 100,
events: bool = False, events: bool = False,
bpmn_name: Optional[str] = None, bpmn_name: str | None = None,
bpmn_identifier: Optional[str] = None, bpmn_identifier: str | None = None,
task_type: Optional[str] = None, task_type: str | None = None,
event_type: Optional[str] = None, event_type: str | None = None,
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
# to make sure the process instance exists # to make sure the process instance exists
process_instance = _find_process_instance_by_id_or_raise(process_instance_id) process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
@ -91,7 +86,7 @@ def log_list(
def typeahead_filter_values( def typeahead_filter_values(
modified_process_model_identifier: str, modified_process_model_identifier: str,
process_instance_id: int, process_instance_id: int,
task_type: Optional[str] = None, task_type: str | None = None,
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
process_instance = _find_process_instance_by_id_or_raise(process_instance_id) process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
query = db.session.query(TaskDefinitionModel.typename).distinct() # type: ignore query = db.session.query(TaskDefinitionModel.typename).distinct() # type: ignore
@ -108,8 +103,8 @@ def typeahead_filter_values(
task_definition_query = task_definition_query.filter(TaskDefinitionModel.typename == task_type) task_definition_query = task_definition_query.filter(TaskDefinitionModel.typename == task_type)
task_definitions = task_definition_query.all() task_definitions = task_definition_query.all()
task_bpmn_names: Set[str] = set() task_bpmn_names: set[str] = set()
task_bpmn_identifiers: Set[str] = set() task_bpmn_identifiers: set[str] = set()
for task_definition in task_definitions: for task_definition in task_definitions:
# not checking for None so we also exclude empty strings # not checking for None so we also exclude empty strings
if task_definition.bpmn_name: if task_definition.bpmn_name:

View File

@ -1,9 +1,6 @@
"""APIs for dealing with process groups, process models, and process instances.""" """APIs for dealing with process groups, process models, and process instances."""
import json import json
from typing import Any from typing import Any
from typing import Dict
from typing import Optional
from typing import Union
import flask.wrappers import flask.wrappers
from flask import current_app from flask import current_app
@ -17,25 +14,17 @@ from sqlalchemy.orm import aliased
from spiffworkflow_backend.exceptions.api_error import ApiError from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.models.bpmn_process import BpmnProcessModel from spiffworkflow_backend.models.bpmn_process import BpmnProcessModel
from spiffworkflow_backend.models.bpmn_process_definition import ( from spiffworkflow_backend.models.bpmn_process_definition import BpmnProcessDefinitionModel
BpmnProcessDefinitionModel,
)
from spiffworkflow_backend.models.db import db from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.human_task import HumanTaskModel from spiffworkflow_backend.models.human_task import HumanTaskModel
from spiffworkflow_backend.models.human_task_user import HumanTaskUserModel from spiffworkflow_backend.models.human_task_user import HumanTaskUserModel
from spiffworkflow_backend.models.json_data import JsonDataModel # noqa: F401 from spiffworkflow_backend.models.json_data import JsonDataModel # noqa: F401
from spiffworkflow_backend.models.process_instance import ProcessInstanceApiSchema from spiffworkflow_backend.models.process_instance import ProcessInstanceApiSchema
from spiffworkflow_backend.models.process_instance import ( from spiffworkflow_backend.models.process_instance import ProcessInstanceCannotBeDeletedError
ProcessInstanceCannotBeDeletedError,
)
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceModelSchema from spiffworkflow_backend.models.process_instance import ProcessInstanceModelSchema
from spiffworkflow_backend.models.process_instance_metadata import ( from spiffworkflow_backend.models.process_instance_metadata import ProcessInstanceMetadataModel
ProcessInstanceMetadataModel, from spiffworkflow_backend.models.process_instance_queue import ProcessInstanceQueueModel
)
from spiffworkflow_backend.models.process_instance_queue import (
ProcessInstanceQueueModel,
)
from spiffworkflow_backend.models.process_instance_report import ProcessInstanceReportModel from spiffworkflow_backend.models.process_instance_report import ProcessInstanceReportModel
from spiffworkflow_backend.models.process_instance_report import Report from spiffworkflow_backend.models.process_instance_report import Report
from spiffworkflow_backend.models.process_model import ProcessModelInfo from spiffworkflow_backend.models.process_model import ProcessModelInfo
@ -43,36 +32,20 @@ from spiffworkflow_backend.models.spec_reference import SpecReferenceCache
from spiffworkflow_backend.models.spec_reference import SpecReferenceNotFoundError from spiffworkflow_backend.models.spec_reference import SpecReferenceNotFoundError
from spiffworkflow_backend.models.task import TaskModel from spiffworkflow_backend.models.task import TaskModel
from spiffworkflow_backend.models.task_definition import TaskDefinitionModel from spiffworkflow_backend.models.task_definition import TaskDefinitionModel
from spiffworkflow_backend.routes.process_api_blueprint import ( from spiffworkflow_backend.routes.process_api_blueprint import _find_process_instance_by_id_or_raise
_find_process_instance_by_id_or_raise,
)
from spiffworkflow_backend.routes.process_api_blueprint import _get_process_model from spiffworkflow_backend.routes.process_api_blueprint import _get_process_model
from spiffworkflow_backend.routes.process_api_blueprint import ( from spiffworkflow_backend.routes.process_api_blueprint import _un_modify_modified_process_model_id
_un_modify_modified_process_model_id,
)
from spiffworkflow_backend.services.authorization_service import AuthorizationService from spiffworkflow_backend.services.authorization_service import AuthorizationService
from spiffworkflow_backend.services.error_handling_service import ErrorHandlingService from spiffworkflow_backend.services.error_handling_service import ErrorHandlingService
from spiffworkflow_backend.services.git_service import GitCommandError from spiffworkflow_backend.services.git_service import GitCommandError
from spiffworkflow_backend.services.git_service import GitService from spiffworkflow_backend.services.git_service import GitService
from spiffworkflow_backend.services.message_service import MessageService from spiffworkflow_backend.services.message_service import MessageService
from spiffworkflow_backend.services.process_instance_processor import ( from spiffworkflow_backend.services.process_instance_processor import ProcessInstanceProcessor
ProcessInstanceProcessor, from spiffworkflow_backend.services.process_instance_queue_service import ProcessInstanceIsAlreadyLockedError
) from spiffworkflow_backend.services.process_instance_queue_service import ProcessInstanceIsNotEnqueuedError
from spiffworkflow_backend.services.process_instance_queue_service import ( from spiffworkflow_backend.services.process_instance_queue_service import ProcessInstanceQueueService
ProcessInstanceIsAlreadyLockedError, from spiffworkflow_backend.services.process_instance_report_service import ProcessInstanceReportService
) from spiffworkflow_backend.services.process_instance_service import ProcessInstanceService
from spiffworkflow_backend.services.process_instance_queue_service import (
ProcessInstanceIsNotEnqueuedError,
)
from spiffworkflow_backend.services.process_instance_queue_service import (
ProcessInstanceQueueService,
)
from spiffworkflow_backend.services.process_instance_report_service import (
ProcessInstanceReportService,
)
from spiffworkflow_backend.services.process_instance_service import (
ProcessInstanceService,
)
from spiffworkflow_backend.services.process_model_service import ProcessModelService from spiffworkflow_backend.services.process_model_service import ProcessModelService
from spiffworkflow_backend.services.spec_file_service import SpecFileService from spiffworkflow_backend.services.spec_file_service import SpecFileService
from spiffworkflow_backend.services.task_service import TaskService from spiffworkflow_backend.services.task_service import TaskService
@ -227,8 +200,8 @@ def process_instance_resume(
def process_instance_list_for_me( def process_instance_list_for_me(
body: Dict[str, Any], body: dict[str, Any],
process_model_identifier: Optional[str] = None, process_model_identifier: str | None = None,
page: int = 1, page: int = 1,
per_page: int = 100, per_page: int = 100,
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
@ -244,8 +217,8 @@ def process_instance_list_for_me(
def process_instance_list( def process_instance_list(
body: Dict[str, Any], body: dict[str, Any],
process_model_identifier: Optional[str] = None, process_model_identifier: str | None = None,
page: int = 1, page: int = 1,
per_page: int = 100, per_page: int = 100,
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
@ -264,9 +237,9 @@ def process_instance_list(
def process_instance_report_show( def process_instance_report_show(
report_hash: Optional[str] = None, report_hash: str | None = None,
report_id: Optional[int] = None, report_id: int | None = None,
report_identifier: Optional[str] = None, report_identifier: str | None = None,
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
if report_hash is None and report_id is None and report_identifier is None: if report_hash is None and report_id is None and report_identifier is None:
raise ApiError( raise ApiError(
@ -276,7 +249,7 @@ def process_instance_report_show(
" report_identifier." " report_identifier."
), ),
) )
response_result: Optional[Union[Report, ProcessInstanceReportModel]] = None response_result: Report | ProcessInstanceReportModel | None = None
if report_hash is not None: if report_hash is not None:
json_data = JsonDataModel.query.filter_by(hash=report_hash).first() json_data = JsonDataModel.query.filter_by(hash=report_hash).first()
if json_data is None: if json_data is None:
@ -297,7 +270,7 @@ def process_instance_report_show(
def process_instance_report_column_list( def process_instance_report_column_list(
process_model_identifier: Optional[str] = None, process_model_identifier: str | None = None,
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
table_columns = ProcessInstanceReportService.builtin_column_options() table_columns = ProcessInstanceReportService.builtin_column_options()
system_report_column_options = ProcessInstanceReportService.system_report_column_options() system_report_column_options = ProcessInstanceReportService.system_report_column_options()
@ -322,7 +295,7 @@ def process_instance_report_column_list(
def process_instance_show_for_me( def process_instance_show_for_me(
modified_process_model_identifier: str, modified_process_model_identifier: str,
process_instance_id: int, process_instance_id: int,
process_identifier: Optional[str] = None, process_identifier: str | None = None,
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
"""Process_instance_show_for_me.""" """Process_instance_show_for_me."""
process_instance = _find_process_instance_for_me_or_raise(process_instance_id) process_instance = _find_process_instance_for_me_or_raise(process_instance_id)
@ -336,7 +309,7 @@ def process_instance_show_for_me(
def process_instance_show( def process_instance_show(
modified_process_model_identifier: str, modified_process_model_identifier: str,
process_instance_id: int, process_instance_id: int,
process_identifier: Optional[str] = None, process_identifier: str | None = None,
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
"""Create_process_instance.""" """Create_process_instance."""
process_instance = _find_process_instance_by_id_or_raise(process_instance_id) process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
@ -375,7 +348,7 @@ def process_instance_report_list(page: int = 1, per_page: int = 100) -> flask.wr
return make_response(jsonify(process_instance_reports), 200) return make_response(jsonify(process_instance_reports), 200)
def process_instance_report_create(body: Dict[str, Any]) -> flask.wrappers.Response: def process_instance_report_create(body: dict[str, Any]) -> flask.wrappers.Response:
process_instance_report = ProcessInstanceReportModel.create_report( process_instance_report = ProcessInstanceReportModel.create_report(
identifier=body["identifier"], identifier=body["identifier"],
user=g.user, user=g.user,
@ -387,7 +360,7 @@ def process_instance_report_create(body: Dict[str, Any]) -> flask.wrappers.Respo
def process_instance_report_update( def process_instance_report_update(
report_id: int, report_id: int,
body: Dict[str, Any], body: dict[str, Any],
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
"""Process_instance_report_update.""" """Process_instance_report_update."""
process_instance_report = ProcessInstanceReportModel.query.filter_by( process_instance_report = ProcessInstanceReportModel.query.filter_by(
@ -432,8 +405,8 @@ def process_instance_task_list_without_task_data_for_me(
modified_process_model_identifier: str, modified_process_model_identifier: str,
process_instance_id: int, process_instance_id: int,
most_recent_tasks_only: bool = False, most_recent_tasks_only: bool = False,
bpmn_process_guid: Optional[str] = None, bpmn_process_guid: str | None = None,
to_task_guid: Optional[str] = None, to_task_guid: str | None = None,
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
"""Process_instance_task_list_without_task_data_for_me.""" """Process_instance_task_list_without_task_data_for_me."""
process_instance = _find_process_instance_for_me_or_raise(process_instance_id) process_instance = _find_process_instance_for_me_or_raise(process_instance_id)
@ -450,8 +423,8 @@ def process_instance_task_list_without_task_data(
modified_process_model_identifier: str, modified_process_model_identifier: str,
process_instance_id: int, process_instance_id: int,
most_recent_tasks_only: bool = False, most_recent_tasks_only: bool = False,
bpmn_process_guid: Optional[str] = None, bpmn_process_guid: str | None = None,
to_task_guid: Optional[str] = None, to_task_guid: str | None = None,
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
"""Process_instance_task_list_without_task_data.""" """Process_instance_task_list_without_task_data."""
process_instance = _find_process_instance_by_id_or_raise(process_instance_id) process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
@ -467,8 +440,8 @@ def process_instance_task_list_without_task_data(
def process_instance_task_list( def process_instance_task_list(
_modified_process_model_identifier: str, _modified_process_model_identifier: str,
process_instance: ProcessInstanceModel, process_instance: ProcessInstanceModel,
bpmn_process_guid: Optional[str] = None, bpmn_process_guid: str | None = None,
to_task_guid: Optional[str] = None, to_task_guid: str | None = None,
most_recent_tasks_only: bool = False, most_recent_tasks_only: bool = False,
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
"""Process_instance_task_list.""" """Process_instance_task_list."""
@ -482,7 +455,7 @@ def process_instance_task_list(
TaskModel.process_instance_id == process_instance.id, TaskModel.process_instance_id == process_instance.id,
) )
to_task_model: Optional[TaskModel] = None to_task_model: TaskModel | None = None
task_models_of_parent_bpmn_processes_guids: list[str] = [] task_models_of_parent_bpmn_processes_guids: list[str] = []
if to_task_guid is not None: if to_task_guid is not None:
to_task_model = TaskModel.query.filter_by(guid=to_task_guid, process_instance_id=process_instance.id).first() to_task_model = TaskModel.query.filter_by(guid=to_task_guid, process_instance_id=process_instance.id).first()
@ -645,7 +618,7 @@ def process_instance_find_by_id(
def send_user_signal_event( def send_user_signal_event(
process_instance_id: int, process_instance_id: int,
body: Dict, body: dict,
) -> Response: ) -> Response:
"""Send a user signal event to a process instance.""" """Send a user signal event to a process instance."""
process_instance = _find_process_instance_for_me_or_raise(process_instance_id) process_instance = _find_process_instance_for_me_or_raise(process_instance_id)
@ -655,7 +628,7 @@ def send_user_signal_event(
def send_bpmn_event( def send_bpmn_event(
modified_process_model_identifier: str, modified_process_model_identifier: str,
process_instance_id: int, process_instance_id: int,
body: Dict, body: dict,
) -> Response: ) -> Response:
"""Send a bpmn event to a process instance.""" """Send a bpmn event to a process instance."""
process_instance = ProcessInstanceModel.query.filter(ProcessInstanceModel.id == int(process_instance_id)).first() process_instance = ProcessInstanceModel.query.filter(ProcessInstanceModel.id == int(process_instance_id)).first()
@ -678,7 +651,7 @@ def _send_bpmn_event(process_instance: ProcessInstanceModel, body: dict) -> Resp
def _get_process_instance( def _get_process_instance(
modified_process_model_identifier: str, modified_process_model_identifier: str,
process_instance: ProcessInstanceModel, process_instance: ProcessInstanceModel,
process_identifier: Optional[str] = None, process_identifier: str | None = None,
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
"""_get_process_instance.""" """_get_process_instance."""
process_model_identifier = modified_process_model_identifier.replace(":", "/") process_model_identifier = modified_process_model_identifier.replace(":", "/")
@ -725,7 +698,7 @@ def _find_process_instance_for_me_or_raise(
process_instance_id: int, process_instance_id: int,
) -> ProcessInstanceModel: ) -> ProcessInstanceModel:
"""_find_process_instance_for_me_or_raise.""" """_find_process_instance_for_me_or_raise."""
process_instance: Optional[ProcessInstanceModel] = ( process_instance: ProcessInstanceModel | None = (
ProcessInstanceModel.query.filter_by(id=process_instance_id) ProcessInstanceModel.query.filter_by(id=process_instance_id)
.outerjoin(HumanTaskModel) .outerjoin(HumanTaskModel)
.outerjoin( .outerjoin(

View File

@ -4,9 +4,6 @@ import os
import re import re
from hashlib import sha256 from hashlib import sha256
from typing import Any from typing import Any
from typing import Dict
from typing import Optional
from typing import Union
import connexion # type: ignore import connexion # type: ignore
import flask.wrappers import flask.wrappers
@ -20,39 +17,27 @@ from werkzeug.datastructures import FileStorage
from spiffworkflow_backend.exceptions.api_error import ApiError from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.interfaces import IdToProcessGroupMapping from spiffworkflow_backend.interfaces import IdToProcessGroupMapping
from spiffworkflow_backend.models.process_group import ProcessGroup from spiffworkflow_backend.models.process_group import ProcessGroup
from spiffworkflow_backend.models.process_instance_report import ( from spiffworkflow_backend.models.process_instance_report import ProcessInstanceReportModel
ProcessInstanceReportModel,
)
from spiffworkflow_backend.models.process_model import ProcessModelInfo from spiffworkflow_backend.models.process_model import ProcessModelInfo
from spiffworkflow_backend.models.process_model import ProcessModelInfoSchema from spiffworkflow_backend.models.process_model import ProcessModelInfoSchema
from spiffworkflow_backend.routes.process_api_blueprint import _commit_and_push_to_git from spiffworkflow_backend.routes.process_api_blueprint import _commit_and_push_to_git
from spiffworkflow_backend.routes.process_api_blueprint import _get_process_model from spiffworkflow_backend.routes.process_api_blueprint import _get_process_model
from spiffworkflow_backend.routes.process_api_blueprint import ( from spiffworkflow_backend.routes.process_api_blueprint import _un_modify_modified_process_model_id
_un_modify_modified_process_model_id,
)
from spiffworkflow_backend.services.file_system_service import FileSystemService from spiffworkflow_backend.services.file_system_service import FileSystemService
from spiffworkflow_backend.services.git_service import GitCommandError from spiffworkflow_backend.services.git_service import GitCommandError
from spiffworkflow_backend.services.git_service import GitService from spiffworkflow_backend.services.git_service import GitService
from spiffworkflow_backend.services.git_service import MissingGitConfigsError from spiffworkflow_backend.services.git_service import MissingGitConfigsError
from spiffworkflow_backend.services.process_instance_report_service import ( from spiffworkflow_backend.services.process_instance_report_service import ProcessInstanceReportNotFoundError
ProcessInstanceReportNotFoundError, from spiffworkflow_backend.services.process_instance_report_service import ProcessInstanceReportService
)
from spiffworkflow_backend.services.process_instance_report_service import (
ProcessInstanceReportService,
)
from spiffworkflow_backend.services.process_model_service import ProcessModelService from spiffworkflow_backend.services.process_model_service import ProcessModelService
from spiffworkflow_backend.services.process_model_service import ( from spiffworkflow_backend.services.process_model_service import ProcessModelWithInstancesNotDeletableError
ProcessModelWithInstancesNotDeletableError,
)
from spiffworkflow_backend.services.process_model_test_runner_service import ProcessModelTestRunner from spiffworkflow_backend.services.process_model_test_runner_service import ProcessModelTestRunner
from spiffworkflow_backend.services.spec_file_service import ( from spiffworkflow_backend.services.spec_file_service import ProcessModelFileInvalidError
ProcessModelFileInvalidError,
)
from spiffworkflow_backend.services.spec_file_service import SpecFileService from spiffworkflow_backend.services.spec_file_service import SpecFileService
def process_model_create( def process_model_create(
modified_process_group_id: str, body: Dict[str, Union[str, bool, int, None, list]] modified_process_group_id: str, body: dict[str, str | bool | int | None | list]
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
"""Process_model_create.""" """Process_model_create."""
body_include_list = [ body_include_list = [
@ -120,7 +105,7 @@ def process_model_delete(
def process_model_update( def process_model_update(
modified_process_model_identifier: str, modified_process_model_identifier: str,
body: Dict[str, Union[str, bool, int, None, list]], body: dict[str, str | bool | int | None | list],
) -> Any: ) -> Any:
"""Process_model_update.""" """Process_model_update."""
process_model_identifier = modified_process_model_identifier.replace(":", "/") process_model_identifier = modified_process_model_identifier.replace(":", "/")
@ -192,7 +177,7 @@ def process_model_move(modified_process_model_identifier: str, new_location: str
def process_model_publish( def process_model_publish(
modified_process_model_identifier: str, branch_to_update: Optional[str] = None modified_process_model_identifier: str, branch_to_update: str | None = None
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
"""Process_model_publish.""" """Process_model_publish."""
if branch_to_update is None: if branch_to_update is None:
@ -209,10 +194,10 @@ def process_model_publish(
def process_model_list( def process_model_list(
process_group_identifier: Optional[str] = None, process_group_identifier: str | None = None,
recursive: Optional[bool] = False, recursive: bool | None = False,
filter_runnable_by_user: Optional[bool] = False, filter_runnable_by_user: bool | None = False,
include_parent_groups: Optional[bool] = False, include_parent_groups: bool | None = False,
page: int = 1, page: int = 1,
per_page: int = 100, per_page: int = 100,
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
@ -318,8 +303,8 @@ def process_model_file_show(modified_process_model_identifier: str, file_name: s
def process_model_test_run( def process_model_test_run(
modified_process_model_identifier: str, modified_process_model_identifier: str,
test_case_file: Optional[str] = None, test_case_file: str | None = None,
test_case_identifier: Optional[str] = None, test_case_identifier: str | None = None,
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
process_model_identifier = modified_process_model_identifier.replace(":", "/") process_model_identifier = modified_process_model_identifier.replace(":", "/")
process_model = _get_process_model(process_model_identifier) process_model = _get_process_model(process_model_identifier)
@ -344,7 +329,7 @@ def process_model_test_run(
# with a bug-details form that collects summary, description, and priority" # with a bug-details form that collects summary, description, and priority"
# } # }
def process_model_create_with_natural_language( def process_model_create_with_natural_language(
modified_process_group_id: str, body: Dict[str, str] modified_process_group_id: str, body: dict[str, str]
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
"""Process_model_create_with_natural_language.""" """Process_model_create_with_natural_language."""
pattern = re.compile( pattern = re.compile(
@ -464,7 +449,7 @@ def process_model_create_with_natural_language(
def _get_file_from_request() -> FileStorage: def _get_file_from_request() -> FileStorage:
"""Get_file_from_request.""" """Get_file_from_request."""
request_file: Optional[FileStorage] = connexion.request.files.get("file") request_file: FileStorage | None = connexion.request.files.get("file")
if not request_file: if not request_file:
raise ApiError( raise ApiError(
error_code="no_file_given", error_code="no_file_given",
@ -503,7 +488,7 @@ def _create_or_update_process_model_file(
modified_process_model_identifier: str, modified_process_model_identifier: str,
message_for_git_commit: str, message_for_git_commit: str,
http_status_to_return: int, http_status_to_return: int,
file_contents_hash: Optional[str] = None, file_contents_hash: str | None = None,
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
"""_create_or_update_process_model_file.""" """_create_or_update_process_model_file."""
process_model_identifier = modified_process_model_identifier.replace(":", "/") process_model_identifier = modified_process_model_identifier.replace(":", "/")

View File

@ -2,8 +2,6 @@
import json import json
import random import random
import string import string
from typing import Dict
from typing import Union
import flask.wrappers import flask.wrappers
from flask import current_app from flask import current_app
@ -15,15 +13,13 @@ from lxml.builder import ElementMaker # type: ignore
from spiffworkflow_backend.exceptions.api_error import ApiError 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_process_model
from spiffworkflow_backend.routes.process_api_blueprint import ( from spiffworkflow_backend.routes.process_api_blueprint import _get_required_parameter_or_raise
_get_required_parameter_or_raise,
)
from spiffworkflow_backend.services.script_unit_test_runner import ScriptUnitTestRunner from spiffworkflow_backend.services.script_unit_test_runner import ScriptUnitTestRunner
from spiffworkflow_backend.services.spec_file_service import SpecFileService from spiffworkflow_backend.services.spec_file_service import SpecFileService
def script_unit_test_create( def script_unit_test_create(
modified_process_model_identifier: str, body: Dict[str, Union[str, bool, int]] modified_process_model_identifier: str, body: dict[str, str | bool | int]
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
"""Script_unit_test_create.""" """Script_unit_test_create."""
bpmn_task_identifier = _get_required_parameter_or_raise("bpmn_task_identifier", body) bpmn_task_identifier = _get_required_parameter_or_raise("bpmn_task_identifier", body)
@ -97,7 +93,7 @@ def script_unit_test_create(
def script_unit_test_run( def script_unit_test_run(
modified_process_model_identifier: str, body: Dict[str, Union[str, bool, int]] modified_process_model_identifier: str, body: dict[str, str | bool | int]
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
"""Script_unit_test_run.""" """Script_unit_test_run."""
# FIXME: We should probably clear this somewhere else but this works # FIXME: We should probably clear this somewhere else but this works

View File

@ -1,6 +1,5 @@
"""APIs for dealing with process groups, process models, and process instances.""" """APIs for dealing with process groups, process models, and process instances."""
import json import json
from typing import Dict
from flask import g from flask import g
from flask import jsonify from flask import jsonify
@ -44,7 +43,7 @@ def secret_list(
return make_response(jsonify(response_json), 200) return make_response(jsonify(response_json), 200)
def secret_create(body: Dict) -> Response: def secret_create(body: dict) -> Response:
"""Add secret.""" """Add secret."""
secret_model = SecretService().add_secret(body["key"], body["value"], g.user.id) secret_model = SecretService().add_secret(body["key"], body["value"], g.user.id)
return Response( return Response(

View File

@ -2,13 +2,10 @@
import json import json
import os import os
import uuid import uuid
from collections.abc import Generator
from sys import exc_info from sys import exc_info
from typing import Any from typing import Any
from typing import Dict
from typing import Generator
from typing import Optional
from typing import TypedDict from typing import TypedDict
from typing import Union
import flask.wrappers import flask.wrappers
import jinja2 import jinja2
@ -40,34 +37,22 @@ from spiffworkflow_backend.models.json_data import JsonDataModel # noqa: F401
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceModelSchema from spiffworkflow_backend.models.process_instance import ProcessInstanceModelSchema
from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus
from spiffworkflow_backend.models.process_instance import ( from spiffworkflow_backend.models.process_instance import ProcessInstanceTaskDataCannotBeUpdatedError
ProcessInstanceTaskDataCannotBeUpdatedError,
)
from spiffworkflow_backend.models.process_instance_event import ProcessInstanceEventType from spiffworkflow_backend.models.process_instance_event import ProcessInstanceEventType
from spiffworkflow_backend.models.process_model import ProcessModelInfo from spiffworkflow_backend.models.process_model import ProcessModelInfo
from spiffworkflow_backend.models.task import Task from spiffworkflow_backend.models.task import Task
from spiffworkflow_backend.models.task import TaskModel from spiffworkflow_backend.models.task import TaskModel
from spiffworkflow_backend.models.user import UserModel from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.routes.process_api_blueprint import ( from spiffworkflow_backend.routes.process_api_blueprint import _find_principal_or_raise
_find_principal_or_raise, from spiffworkflow_backend.routes.process_api_blueprint import _find_process_instance_by_id_or_raise
)
from spiffworkflow_backend.routes.process_api_blueprint import (
_find_process_instance_by_id_or_raise,
)
from spiffworkflow_backend.routes.process_api_blueprint import _get_process_model from spiffworkflow_backend.routes.process_api_blueprint import _get_process_model
from spiffworkflow_backend.services.authorization_service import AuthorizationService from spiffworkflow_backend.services.authorization_service import AuthorizationService
from spiffworkflow_backend.services.authorization_service import HumanTaskNotFoundError from spiffworkflow_backend.services.authorization_service import HumanTaskNotFoundError
from spiffworkflow_backend.services.authorization_service import UserDoesNotHaveAccessToTaskError from spiffworkflow_backend.services.authorization_service import UserDoesNotHaveAccessToTaskError
from spiffworkflow_backend.services.file_system_service import FileSystemService from spiffworkflow_backend.services.file_system_service import FileSystemService
from spiffworkflow_backend.services.process_instance_processor import ( from spiffworkflow_backend.services.process_instance_processor import ProcessInstanceProcessor
ProcessInstanceProcessor, from spiffworkflow_backend.services.process_instance_queue_service import ProcessInstanceQueueService
) from spiffworkflow_backend.services.process_instance_service import ProcessInstanceService
from spiffworkflow_backend.services.process_instance_queue_service import (
ProcessInstanceQueueService,
)
from spiffworkflow_backend.services.process_instance_service import (
ProcessInstanceService,
)
from spiffworkflow_backend.services.process_instance_tmp_service import ProcessInstanceTmpService from spiffworkflow_backend.services.process_instance_tmp_service import ProcessInstanceTmpService
from spiffworkflow_backend.services.process_model_service import ProcessModelService from spiffworkflow_backend.services.process_model_service import ProcessModelService
from spiffworkflow_backend.services.spec_file_service import SpecFileService from spiffworkflow_backend.services.spec_file_service import SpecFileService
@ -91,7 +76,7 @@ class ReactJsonSchemaSelectOption(TypedDict):
def task_list_my_tasks( def task_list_my_tasks(
process_instance_id: Optional[int] = None, page: int = 1, per_page: int = 100 process_instance_id: int | None = None, page: int = 1, per_page: int = 100
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
"""Task_list_my_tasks.""" """Task_list_my_tasks."""
principal = _find_principal_or_raise() principal = _find_principal_or_raise()
@ -172,7 +157,7 @@ def task_list_for_me(page: int = 1, per_page: int = 100) -> flask.wrappers.Respo
def task_list_for_my_groups( def task_list_for_my_groups(
user_group_identifier: Optional[str] = None, page: int = 1, per_page: int = 100 user_group_identifier: str | None = None, page: int = 1, per_page: int = 100
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
"""Task_list_for_my_groups.""" """Task_list_for_my_groups."""
return _get_tasks( return _get_tasks(
@ -197,7 +182,7 @@ def task_data_update(
process_instance_id: str, process_instance_id: str,
modified_process_model_identifier: str, modified_process_model_identifier: str,
task_guid: str, task_guid: str,
body: Dict, body: dict,
) -> Response: ) -> Response:
"""Update task data.""" """Update task data."""
process_instance = ProcessInstanceModel.query.filter(ProcessInstanceModel.id == int(process_instance_id)).first() process_instance = ProcessInstanceModel.query.filter(ProcessInstanceModel.id == int(process_instance_id)).first()
@ -250,7 +235,7 @@ def manual_complete_task(
modified_process_model_identifier: str, modified_process_model_identifier: str,
process_instance_id: str, process_instance_id: str,
task_guid: str, task_guid: str,
body: Dict, body: dict,
) -> Response: ) -> Response:
"""Mark a task complete without executing it.""" """Mark a task complete without executing it."""
execute = body.get("execute", True) execute = body.get("execute", True)
@ -371,7 +356,7 @@ def task_show(process_instance_id: int, task_guid: str = "next") -> flask.wrappe
return make_response(jsonify(task_model), 200) return make_response(jsonify(task_model), 200)
def _render_instructions_for_end_user(task_model: TaskModel, extensions: Optional[dict] = None) -> str: def _render_instructions_for_end_user(task_model: TaskModel, extensions: dict | None = None) -> str:
"""Assure any instructions for end user are processed for jinja syntax.""" """Assure any instructions for end user are processed for jinja syntax."""
if extensions is None: if extensions is None:
extensions = TaskService.get_extensions_from_task_model(task_model) extensions = TaskService.get_extensions_from_task_model(task_model)
@ -387,7 +372,7 @@ def _render_instructions_for_end_user(task_model: TaskModel, extensions: Optiona
return "" return ""
def _interstitial_stream(process_instance: ProcessInstanceModel) -> Generator[str, Optional[str], None]: def _interstitial_stream(process_instance: ProcessInstanceModel) -> Generator[str, str | None, None]:
def get_reportable_tasks() -> Any: def get_reportable_tasks() -> Any:
return processor.bpmn_process_instance.get_tasks( return processor.bpmn_process_instance.get_tasks(
TaskState.WAITING | TaskState.STARTED | TaskState.READY | TaskState.ERROR TaskState.WAITING | TaskState.STARTED | TaskState.READY | TaskState.ERROR
@ -398,7 +383,7 @@ def _interstitial_stream(process_instance: ProcessInstanceModel) -> Generator[st
extensions = TaskService.get_extensions_from_task_model(task_model) extensions = TaskService.get_extensions_from_task_model(task_model)
return _render_instructions_for_end_user(task_model, extensions) return _render_instructions_for_end_user(task_model, extensions)
def render_data(return_type: str, entity: Union[ApiError, Task, ProcessInstanceModel]) -> str: def render_data(return_type: str, entity: ApiError | Task | ProcessInstanceModel) -> str:
return_hash: dict = {"type": return_type} return_hash: dict = {"type": return_type}
return_hash[return_type] = entity return_hash[return_type] = entity
return f"data: {current_app.json.dumps(return_hash)} \n\n" return f"data: {current_app.json.dumps(return_hash)} \n\n"
@ -465,7 +450,7 @@ def get_ready_engine_step_count(bpmn_process_instance: BpmnWorkflow) -> int:
return len(list([t for t in bpmn_process_instance.get_tasks(TaskState.READY) if not t.task_spec.manual])) return len(list([t for t in bpmn_process_instance.get_tasks(TaskState.READY) if not t.task_spec.manual]))
def _dequeued_interstitial_stream(process_instance_id: int) -> Generator[Optional[str], Optional[str], None]: def _dequeued_interstitial_stream(process_instance_id: int) -> Generator[str | None, str | None, None]:
process_instance = _find_process_instance_by_id_or_raise(process_instance_id) process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
# TODO: currently this just redirects back to home if the process has not been started # TODO: currently this just redirects back to home if the process has not been started
@ -488,7 +473,7 @@ def interstitial(process_instance_id: int) -> Response:
def _task_submit_shared( def _task_submit_shared(
process_instance_id: int, process_instance_id: int,
task_guid: str, task_guid: str,
body: Dict[str, Any], body: dict[str, Any],
save_as_draft: bool = False, save_as_draft: bool = False,
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
principal = _find_principal_or_raise() principal = _find_principal_or_raise()
@ -586,7 +571,7 @@ def _task_submit_shared(
def task_submit( def task_submit(
process_instance_id: int, process_instance_id: int,
task_guid: str, task_guid: str,
body: Dict[str, Any], body: dict[str, Any],
save_as_draft: bool = False, save_as_draft: bool = False,
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
"""Task_submit_user_data.""" """Task_submit_user_data."""
@ -599,7 +584,7 @@ def _get_tasks(
has_lane_assignment_id: bool = True, has_lane_assignment_id: bool = True,
page: int = 1, page: int = 1,
per_page: int = 100, per_page: int = 100,
user_group_identifier: Optional[str] = None, user_group_identifier: str | None = None,
) -> flask.wrappers.Response: ) -> flask.wrappers.Response:
"""Get_tasks.""" """Get_tasks."""
user_id = g.user.id user_id = g.user.id
@ -748,7 +733,7 @@ def _render_jinja_template(unprocessed_template: str, task_model: TaskModel) ->
def _get_spiff_task_from_process_instance( def _get_spiff_task_from_process_instance(
task_guid: str, task_guid: str,
process_instance: ProcessInstanceModel, process_instance: ProcessInstanceModel,
processor: Union[ProcessInstanceProcessor, None] = None, processor: ProcessInstanceProcessor | None = None,
) -> SpiffTask: ) -> SpiffTask:
"""Get_spiff_task_from_process_instance.""" """Get_spiff_task_from_process_instance."""
if processor is None: if processor is None:
@ -881,7 +866,7 @@ def _munge_form_ui_schema_based_on_hidden_fields_in_task_data(task_model: TaskMo
def _get_task_model_from_guid_or_raise(task_guid: str, process_instance_id: int) -> TaskModel: def _get_task_model_from_guid_or_raise(task_guid: str, process_instance_id: int) -> TaskModel:
task_model: Optional[TaskModel] = TaskModel.query.filter_by( task_model: TaskModel | None = TaskModel.query.filter_by(
guid=task_guid, process_instance_id=process_instance_id guid=task_guid, process_instance_id=process_instance_id
).first() ).first()
if task_model is None: if task_model is None:

View File

@ -4,8 +4,6 @@ import base64
import json import json
import re import re
from typing import Any from typing import Any
from typing import Dict
from typing import Optional
import flask import flask
import jwt import jwt
@ -20,14 +18,12 @@ from werkzeug.wrappers import Response
from spiffworkflow_backend.exceptions.api_error import ApiError from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.helpers.api_version import V1_API_PATH_PREFIX from spiffworkflow_backend.helpers.api_version import V1_API_PATH_PREFIX
from spiffworkflow_backend.models.db import db from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.group import GroupModel
from spiffworkflow_backend.models.group import SPIFF_NO_AUTH_ANONYMOUS_GROUP from spiffworkflow_backend.models.group import SPIFF_NO_AUTH_ANONYMOUS_GROUP
from spiffworkflow_backend.models.group import GroupModel
from spiffworkflow_backend.models.user import SPIFF_NO_AUTH_ANONYMOUS_USER from spiffworkflow_backend.models.user import SPIFF_NO_AUTH_ANONYMOUS_USER
from spiffworkflow_backend.models.user import UserModel from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.services.authentication_service import AuthenticationService from spiffworkflow_backend.services.authentication_service import AuthenticationService
from spiffworkflow_backend.services.authentication_service import ( from spiffworkflow_backend.services.authentication_service import MissingAccessTokenError
MissingAccessTokenError,
)
from spiffworkflow_backend.services.authentication_service import TokenExpiredError from spiffworkflow_backend.services.authentication_service import TokenExpiredError
from spiffworkflow_backend.services.authorization_service import AuthorizationService from spiffworkflow_backend.services.authorization_service import AuthorizationService
from spiffworkflow_backend.services.group_service import GroupService from spiffworkflow_backend.services.group_service import GroupService
@ -40,7 +36,7 @@ from spiffworkflow_backend.services.user_service import UserService
# authorization_exclusion_list = ['status'] # authorization_exclusion_list = ['status']
def verify_token(token: Optional[str] = None, force_run: Optional[bool] = False) -> None: def verify_token(token: str | None = None, force_run: bool | None = False) -> None:
"""Verify the token for the user (if provided). """Verify the token for the user (if provided).
If in production environment and token is not provided, gets user from the SSO headers and returns their token. If in production environment and token is not provided, gets user from the SSO headers and returns their token.
@ -189,7 +185,7 @@ def set_new_access_token_in_cookie(
It will also delete the cookies if the user has logged out. It will also delete the cookies if the user has logged out.
""" """
tld = current_app.config["THREAD_LOCAL_DATA"] tld = current_app.config["THREAD_LOCAL_DATA"]
domain_for_frontend_cookie: Optional[str] = re.sub( domain_for_frontend_cookie: str | None = re.sub(
r"^https?:\/\/", r"^https?:\/\/",
"", "",
current_app.config["SPIFFWORKFLOW_BACKEND_URL_FOR_FRONTEND"], current_app.config["SPIFFWORKFLOW_BACKEND_URL_FOR_FRONTEND"],
@ -247,7 +243,7 @@ def parse_id_token(token: str) -> Any:
return json.loads(decoded) return json.loads(decoded)
def login_return(code: str, state: str, session_state: str = "") -> Optional[Response]: def login_return(code: str, state: str, session_state: str = "") -> Response | None:
state_dict = ast.literal_eval(base64.b64decode(state).decode("utf-8")) state_dict = ast.literal_eval(base64.b64decode(state).decode("utf-8"))
state_redirect_url = state_dict["redirect_url"] state_redirect_url = state_dict["redirect_url"]
auth_token_object = AuthenticationService().get_auth_token_object(code) auth_token_object = AuthenticationService().get_auth_token_object(code)
@ -320,7 +316,7 @@ def login_api_return(code: str, state: str, session_state: str) -> str:
return access_token return access_token
def logout(id_token: str, redirect_url: Optional[str]) -> Response: def logout(id_token: str, redirect_url: str | None) -> Response:
"""Logout.""" """Logout."""
if redirect_url is None: if redirect_url is None:
redirect_url = "" redirect_url = ""
@ -335,7 +331,7 @@ def logout_return() -> Response:
return redirect(f"{frontend_url}/") return redirect(f"{frontend_url}/")
def get_decoded_token(token: str) -> Optional[Dict]: def get_decoded_token(token: str) -> dict | None:
"""Get_token_type.""" """Get_token_type."""
try: try:
decoded_token = jwt.decode(token, options={"verify_signature": False}) decoded_token = jwt.decode(token, options={"verify_signature": False})
@ -361,7 +357,7 @@ def get_scope(token: str) -> str:
return scope return scope
def get_user_from_decoded_internal_token(decoded_token: dict) -> Optional[UserModel]: def get_user_from_decoded_internal_token(decoded_token: dict) -> UserModel | None:
"""Get_user_from_decoded_internal_token.""" """Get_user_from_decoded_internal_token."""
sub = decoded_token["sub"] sub = decoded_token["sub"]
parts = sub.split("::") parts = sub.split("::")

View File

@ -5,8 +5,8 @@ from typing import Final
import flask.wrappers import flask.wrappers
from flask import Blueprint from flask import Blueprint
from flask import request
from flask import Response from flask import Response
from flask import request
from sqlalchemy.exc import IntegrityError from sqlalchemy.exc import IntegrityError
from spiffworkflow_backend.exceptions.api_error import ApiError from spiffworkflow_backend.exceptions.api_error import ApiError

View File

@ -1,6 +1,5 @@
"""Users_controller.""" """Users_controller."""
from typing import Any from typing import Any
from typing import Dict
import flask import flask
from flask import current_app from flask import current_app
@ -12,7 +11,7 @@ from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.models.user import UserModel from spiffworkflow_backend.models.user import UserModel
def user_exists_by_username(body: Dict[str, Any]) -> flask.wrappers.Response: def user_exists_by_username(body: dict[str, Any]) -> flask.wrappers.Response:
if "username" not in body: if "username" not in body:
raise ApiError( raise ApiError(
error_code="username_not_given", error_code="username_not_given",

View File

@ -2,14 +2,11 @@
from time import time from time import time
from typing import Any from typing import Any
from sqlalchemy import or_
from spiffworkflow_backend.models.db import db from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.script_attributes_context import ( from spiffworkflow_backend.models.script_attributes_context import ScriptAttributesContext
ScriptAttributesContext,
)
from spiffworkflow_backend.scripts.script import Script from spiffworkflow_backend.scripts.script import Script
from sqlalchemy import or_
class DeleteProcessInstancesWithCriteria(Script): class DeleteProcessInstancesWithCriteria(Script):

View File

@ -1,9 +1,7 @@
"""Fact_service.""" """Fact_service."""
from typing import Any from typing import Any
from spiffworkflow_backend.models.script_attributes_context import ( from spiffworkflow_backend.models.script_attributes_context import ScriptAttributesContext
ScriptAttributesContext,
)
from spiffworkflow_backend.scripts.script import Script from spiffworkflow_backend.scripts.script import Script

View File

@ -6,9 +6,7 @@ from spiffworkflow_backend.models.group import GroupModel
from spiffworkflow_backend.models.permission_assignment import PermissionAssignmentModel from spiffworkflow_backend.models.permission_assignment import PermissionAssignmentModel
from spiffworkflow_backend.models.permission_target import PermissionTargetModel from spiffworkflow_backend.models.permission_target import PermissionTargetModel
from spiffworkflow_backend.models.principal import PrincipalModel from spiffworkflow_backend.models.principal import PrincipalModel
from spiffworkflow_backend.models.script_attributes_context import ( from spiffworkflow_backend.models.script_attributes_context import ScriptAttributesContext
ScriptAttributesContext,
)
from spiffworkflow_backend.scripts.script import Script from spiffworkflow_backend.scripts.script import Script

View File

@ -3,10 +3,7 @@ from typing import Any
from flask import current_app from flask import current_app
from flask import g from flask import g
from spiffworkflow_backend.models.script_attributes_context import ScriptAttributesContext
from spiffworkflow_backend.models.script_attributes_context import (
ScriptAttributesContext,
)
from spiffworkflow_backend.scripts.script import Script from spiffworkflow_backend.scripts.script import Script

View File

@ -1,13 +1,9 @@
"""Get_data_sizes.""" """Get_data_sizes."""
from typing import Any from typing import Any
from spiffworkflow_backend.models.script_attributes_context import ( from spiffworkflow_backend.models.script_attributes_context import ScriptAttributesContext
ScriptAttributesContext,
)
from spiffworkflow_backend.scripts.script import Script from spiffworkflow_backend.scripts.script import Script
from spiffworkflow_backend.services.process_instance_processor import ( from spiffworkflow_backend.services.process_instance_processor import ProcessInstanceProcessor
ProcessInstanceProcessor,
)
class TaskNotGivenToScriptError(Exception): class TaskNotGivenToScriptError(Exception):

View File

@ -2,12 +2,8 @@
import base64 import base64
from typing import Any from typing import Any
from spiffworkflow_backend.models.process_instance_file_data import ( from spiffworkflow_backend.models.process_instance_file_data import ProcessInstanceFileDataModel
ProcessInstanceFileDataModel, from spiffworkflow_backend.models.script_attributes_context import ScriptAttributesContext
)
from spiffworkflow_backend.models.script_attributes_context import (
ScriptAttributesContext,
)
from spiffworkflow_backend.scripts.script import Script from spiffworkflow_backend.scripts.script import Script

View File

@ -1,9 +1,7 @@
"""Get_env.""" """Get_env."""
from typing import Any from typing import Any
from spiffworkflow_backend.models.script_attributes_context import ( from spiffworkflow_backend.models.script_attributes_context import ScriptAttributesContext
ScriptAttributesContext,
)
from spiffworkflow_backend.scripts.script import Script from spiffworkflow_backend.scripts.script import Script

View File

@ -2,10 +2,7 @@
from typing import Any from typing import Any
from flask import current_app from flask import current_app
from spiffworkflow_backend.models.script_attributes_context import ScriptAttributesContext
from spiffworkflow_backend.models.script_attributes_context import (
ScriptAttributesContext,
)
from spiffworkflow_backend.scripts.script import Script from spiffworkflow_backend.scripts.script import Script

View File

@ -3,9 +3,7 @@ from typing import Any
from spiffworkflow_backend.models.group import GroupModel from spiffworkflow_backend.models.group import GroupModel
from spiffworkflow_backend.models.group import GroupNotFoundError from spiffworkflow_backend.models.group import GroupNotFoundError
from spiffworkflow_backend.models.script_attributes_context import ( from spiffworkflow_backend.models.script_attributes_context import ScriptAttributesContext
ScriptAttributesContext,
)
from spiffworkflow_backend.scripts.script import Script from spiffworkflow_backend.scripts.script import Script

View File

@ -2,9 +2,7 @@
from typing import Any from typing import Any
from spiffworkflow_backend.models.human_task import HumanTaskModel from spiffworkflow_backend.models.human_task import HumanTaskModel
from spiffworkflow_backend.models.script_attributes_context import ( from spiffworkflow_backend.models.script_attributes_context import ScriptAttributesContext
ScriptAttributesContext,
)
from spiffworkflow_backend.models.user import UserModel from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.scripts.script import Script from spiffworkflow_backend.scripts.script import Script

View File

@ -3,11 +3,8 @@ from datetime import datetime
from typing import Any from typing import Any
import pytz 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 ( from spiffworkflow_backend.models.script_attributes_context import ScriptAttributesContext
ScriptAttributesContext,
)
from spiffworkflow_backend.scripts.script import Script from spiffworkflow_backend.scripts.script import Script

View File

@ -2,9 +2,7 @@
from typing import Any from typing import Any
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.script_attributes_context import ( from spiffworkflow_backend.models.script_attributes_context import ScriptAttributesContext
ScriptAttributesContext,
)
from spiffworkflow_backend.models.user import UserModel from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.scripts.script import Script from spiffworkflow_backend.scripts.script import Script

View File

@ -1,9 +1,7 @@
"""Get_secret.""" """Get_secret."""
from typing import Any from typing import Any
from spiffworkflow_backend.models.script_attributes_context import ( from spiffworkflow_backend.models.script_attributes_context import ScriptAttributesContext
ScriptAttributesContext,
)
from spiffworkflow_backend.scripts.script import Script from spiffworkflow_backend.scripts.script import Script
from spiffworkflow_backend.services.secret_service import SecretService from spiffworkflow_backend.services.secret_service import SecretService

View File

@ -1,9 +1,7 @@
"""Get_process_info.""" """Get_process_info."""
from typing import Any from typing import Any
from spiffworkflow_backend.models.script_attributes_context import ( from spiffworkflow_backend.models.script_attributes_context import ScriptAttributesContext
ScriptAttributesContext,
)
from spiffworkflow_backend.scripts.script import Script from spiffworkflow_backend.scripts.script import Script

View File

@ -2,11 +2,8 @@
from typing import Any from typing import Any
from flask import current_app from flask import current_app
from spiffworkflow_backend.models.process_model import ProcessModelInfo from spiffworkflow_backend.models.process_model import ProcessModelInfo
from spiffworkflow_backend.models.script_attributes_context import ( from spiffworkflow_backend.models.script_attributes_context import ScriptAttributesContext
ScriptAttributesContext,
)
from spiffworkflow_backend.scripts.script import Script from spiffworkflow_backend.scripts.script import Script

View File

@ -1,9 +1,7 @@
"""Get_env.""" """Get_env."""
from typing import Any from typing import Any
from spiffworkflow_backend.models.script_attributes_context import ( from spiffworkflow_backend.models.script_attributes_context import ScriptAttributesContext
ScriptAttributesContext,
)
from spiffworkflow_backend.scripts.script import Script from spiffworkflow_backend.scripts.script import Script
from spiffworkflow_backend.services.authorization_service import AuthorizationService from spiffworkflow_backend.services.authorization_service import AuthorizationService

View File

@ -5,15 +5,13 @@ import importlib
import os import os
import pkgutil import pkgutil
from abc import abstractmethod from abc import abstractmethod
from collections.abc import Callable
from typing import Any from typing import Any
from typing import Callable
from spiffworkflow_backend.exceptions.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 ProcessInstanceModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceNotFoundError from spiffworkflow_backend.models.process_instance import ProcessInstanceNotFoundError
from spiffworkflow_backend.models.script_attributes_context import ( from spiffworkflow_backend.models.script_attributes_context import ScriptAttributesContext
ScriptAttributesContext,
)
from spiffworkflow_backend.services.authorization_service import AuthorizationService from spiffworkflow_backend.services.authorization_service import AuthorizationService
# Generally speaking, having some global in a flask app is TERRIBLE. # Generally speaking, having some global in a flask app is TERRIBLE.

View File

@ -2,14 +2,12 @@
import time import time
from flask import current_app from flask import current_app
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
from spiffworkflow_backend.models.db import db from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus
from spiffworkflow_backend.services.process_instance_service import ( from spiffworkflow_backend.services.process_instance_service import ProcessInstanceService
ProcessInstanceService,
) from tests.spiffworkflow_backend.helpers.base_test import BaseTest
def load_acceptance_test_fixtures() -> list[ProcessInstanceModel]: def load_acceptance_test_fixtures() -> list[ProcessInstanceModel]:

View File

@ -1,6 +1,6 @@
"""Assertion_service.""" """Assertion_service."""
import contextlib import contextlib
from typing import Generator from collections.abc import Generator
import sentry_sdk import sentry_sdk
from flask import current_app from flask import current_app

View File

@ -2,16 +2,14 @@ import base64
import enum import enum
import json import json
import time import time
from typing import Optional
import jwt import jwt
import requests import requests
from flask import current_app from flask import current_app
from flask import redirect from flask import redirect
from werkzeug.wrappers import Response
from spiffworkflow_backend.models.db import db from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.refresh_token import RefreshTokenModel from spiffworkflow_backend.models.refresh_token import RefreshTokenModel
from werkzeug.wrappers import Response
class MissingAccessTokenError(Exception): class MissingAccessTokenError(Exception):
@ -93,7 +91,7 @@ class AuthenticationService:
"""Get_backend_url.""" """Get_backend_url."""
return str(current_app.config["SPIFFWORKFLOW_BACKEND_URL"]) return str(current_app.config["SPIFFWORKFLOW_BACKEND_URL"])
def logout(self, id_token: str, redirect_url: Optional[str] = None) -> Response: def logout(self, id_token: str, redirect_url: str | None = None) -> Response:
"""Logout.""" """Logout."""
if redirect_url is None: if redirect_url is None:
redirect_url = f"{self.get_backend_url()}/v1.0/logout_return" redirect_url = f"{self.get_backend_url()}/v1.0/logout_return"
@ -217,7 +215,7 @@ class AuthenticationService:
) from e ) from e
@staticmethod @staticmethod
def get_refresh_token(user_id: int) -> Optional[str]: def get_refresh_token(user_id: int) -> str | None:
"""Get_refresh_token.""" """Get_refresh_token."""
refresh_token_object: RefreshTokenModel = RefreshTokenModel.query.filter( refresh_token_object: RefreshTokenModel = RefreshTokenModel.query.filter(
RefreshTokenModel.user_id == user_id RefreshTokenModel.user_id == user_id

View File

@ -2,12 +2,9 @@ import inspect
import re import re
from dataclasses import dataclass from dataclasses import dataclass
from hashlib import sha256 from hashlib import sha256
from hmac import compare_digest
from hmac import HMAC from hmac import HMAC
from typing import Optional from hmac import compare_digest
from typing import Set
from typing import TypedDict from typing import TypedDict
from typing import Union
import jwt import jwt
import yaml import yaml
@ -15,9 +12,6 @@ from flask import current_app
from flask import g from flask import g
from flask import request from flask import request
from flask import scaffold from flask import scaffold
from sqlalchemy import or_
from sqlalchemy import text
from spiffworkflow_backend.helpers.api_version import V1_API_PATH_PREFIX from spiffworkflow_backend.helpers.api_version import V1_API_PATH_PREFIX
from spiffworkflow_backend.models.db import db from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.group import GroupModel from spiffworkflow_backend.models.group import GroupModel
@ -36,6 +30,8 @@ from spiffworkflow_backend.services.authentication_service import TokenNotProvid
from spiffworkflow_backend.services.authentication_service import UserNotLoggedInError from spiffworkflow_backend.services.authentication_service import UserNotLoggedInError
from spiffworkflow_backend.services.group_service import GroupService from spiffworkflow_backend.services.group_service import GroupService
from spiffworkflow_backend.services.user_service import UserService from spiffworkflow_backend.services.user_service import UserService
from sqlalchemy import or_
from sqlalchemy import text
class PermissionsFileNotSetError(Exception): class PermissionsFileNotSetError(Exception):
@ -91,7 +87,7 @@ class UserToGroupDict(TypedDict):
class AddedPermissionDict(TypedDict): class AddedPermissionDict(TypedDict):
group_identifiers: Set[str] group_identifiers: set[str]
permission_assignments: list[PermissionAssignmentModel] permission_assignments: list[PermissionAssignmentModel]
user_to_group_identifiers: list[UserToGroupDict] user_to_group_identifiers: list[UserToGroupDict]
@ -112,7 +108,7 @@ class AuthorizationService:
# https://stackoverflow.com/a/71320673/6090676 # https://stackoverflow.com/a/71320673/6090676
@classmethod @classmethod
def verify_sha256_token(cls, auth_header: Optional[str]) -> None: def verify_sha256_token(cls, auth_header: str | None) -> None:
if auth_header is None: if auth_header is None:
raise TokenNotProvidedError( raise TokenNotProvidedError(
"unauthorized", "unauthorized",
@ -189,7 +185,7 @@ class AuthorizationService:
db.session.commit() db.session.commit()
@classmethod @classmethod
def import_permissions_from_yaml_file(cls, user_model: Optional[UserModel] = None) -> AddedPermissionDict: def import_permissions_from_yaml_file(cls, user_model: UserModel | None = None) -> AddedPermissionDict:
group_permissions = cls.parse_permissions_yaml_into_group_info() group_permissions = cls.parse_permissions_yaml_into_group_info()
result = cls.add_permissions_from_group_permissions(group_permissions, user_model) result = cls.add_permissions_from_group_permissions(group_permissions, user_model)
return result return result
@ -198,7 +194,7 @@ class AuthorizationService:
def find_or_create_permission_target(cls, uri: str) -> PermissionTargetModel: def find_or_create_permission_target(cls, uri: str) -> PermissionTargetModel:
uri_with_percent = re.sub(r"\*", "%", uri) uri_with_percent = re.sub(r"\*", "%", uri)
target_uri_normalized = uri_with_percent.removeprefix(V1_API_PATH_PREFIX) target_uri_normalized = uri_with_percent.removeprefix(V1_API_PATH_PREFIX)
permission_target: Optional[PermissionTargetModel] = PermissionTargetModel.query.filter_by( permission_target: PermissionTargetModel | None = PermissionTargetModel.query.filter_by(
uri=target_uri_normalized uri=target_uri_normalized
).first() ).first()
if permission_target is None: if permission_target is None:
@ -214,7 +210,7 @@ class AuthorizationService:
permission_target: PermissionTargetModel, permission_target: PermissionTargetModel,
permission: str, permission: str,
) -> PermissionAssignmentModel: ) -> PermissionAssignmentModel:
permission_assignment: Optional[PermissionAssignmentModel] = PermissionAssignmentModel.query.filter_by( permission_assignment: PermissionAssignmentModel | None = PermissionAssignmentModel.query.filter_by(
principal_id=principal.id, principal_id=principal.id,
permission_target_id=permission_target.id, permission_target_id=permission_target.id,
permission=permission, permission=permission,
@ -268,7 +264,7 @@ class AuthorizationService:
return False return False
@classmethod @classmethod
def get_permission_from_http_method(cls, http_method: str) -> Optional[str]: def get_permission_from_http_method(cls, http_method: str) -> str | None:
request_method_mapper = { request_method_mapper = {
"POST": "create", "POST": "create",
"GET": "read", "GET": "read",
@ -319,7 +315,7 @@ class AuthorizationService:
) )
@staticmethod @staticmethod
def decode_auth_token(auth_token: str) -> dict[str, Union[str, None]]: def decode_auth_token(auth_token: str) -> dict[str, str | None]:
secret_key = current_app.config.get("SECRET_KEY") secret_key = current_app.config.get("SECRET_KEY")
if secret_key is None: if secret_key is None:
raise KeyError("we need current_app.config to have a SECRET_KEY") raise KeyError("we need current_app.config to have a SECRET_KEY")
@ -687,9 +683,9 @@ class AuthorizationService:
@classmethod @classmethod
def add_permissions_from_group_permissions( def add_permissions_from_group_permissions(
cls, group_permissions: list[GroupPermissionsDict], user_model: Optional[UserModel] = None cls, group_permissions: list[GroupPermissionsDict], user_model: UserModel | None = None
) -> AddedPermissionDict: ) -> AddedPermissionDict:
unique_user_group_identifiers: Set[str] = set() unique_user_group_identifiers: set[str] = set()
user_to_group_identifiers: list[UserToGroupDict] = [] user_to_group_identifiers: list[UserToGroupDict] = []
permission_assignments = [] permission_assignments = []

View File

@ -1,14 +1,9 @@
"""Background_processing_service.""" """Background_processing_service."""
import flask import flask
from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus
from spiffworkflow_backend.services.message_service import MessageService from spiffworkflow_backend.services.message_service import MessageService
from spiffworkflow_backend.services.process_instance_lock_service import ( from spiffworkflow_backend.services.process_instance_lock_service import ProcessInstanceLockService
ProcessInstanceLockService, from spiffworkflow_backend.services.process_instance_service import ProcessInstanceService
)
from spiffworkflow_backend.services.process_instance_service import (
ProcessInstanceService,
)
class BackgroundProcessingService: class BackgroundProcessingService:

View File

@ -1,7 +1,6 @@
"""Custom_parser.""" """Custom_parser."""
from SpiffWorkflow.dmn.parser.BpmnDmnParser import BpmnDmnParser # type: ignore from SpiffWorkflow.dmn.parser.BpmnDmnParser import BpmnDmnParser # type: ignore
from SpiffWorkflow.spiff.parser.process import SpiffBpmnParser # type: ignore from SpiffWorkflow.spiff.parser.process import SpiffBpmnParser # type: ignore
from spiffworkflow_backend.specs.start_event import StartEvent from spiffworkflow_backend.specs.start_event import StartEvent

View File

@ -1,6 +1,5 @@
"""Data_setup_service.""" """Data_setup_service."""
from flask import current_app 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.process_model_service import ProcessModelService
from spiffworkflow_backend.services.spec_file_service import SpecFileService from spiffworkflow_backend.services.spec_file_service import SpecFileService

View File

@ -1,18 +1,16 @@
import json import json
from typing import Any from typing import Any
from typing import Dict
from typing import Optional
from flask import current_app from flask import current_app
BpmnSpecDict = Dict[str, Any] BpmnSpecDict = dict[str, Any]
class ElementUnitsService: class ElementUnitsService:
"""Feature gated glue between the backend and spiff-element-units.""" """Feature gated glue between the backend and spiff-element-units."""
@classmethod @classmethod
def _cache_dir(cls) -> Optional[str]: def _cache_dir(cls) -> str | None:
return current_app.config["SPIFFWORKFLOW_BACKEND_ELEMENT_UNITS_CACHE_DIR"] # type: ignore return current_app.config["SPIFFWORKFLOW_BACKEND_ELEMENT_UNITS_CACHE_DIR"] # type: ignore
@classmethod @classmethod
@ -45,7 +43,7 @@ class ElementUnitsService:
@classmethod @classmethod
def workflow_from_cached_element_unit( def workflow_from_cached_element_unit(
cls, cache_key: str, process_id: str, element_id: str cls, cache_key: str, process_id: str, element_id: str
) -> Optional[BpmnSpecDict]: ) -> BpmnSpecDict | None:
if not cls._enabled(): if not cls._enabled():
return None return None

View File

@ -1,6 +1,4 @@
"""Email_service.""" """Email_service."""
from typing import List
from typing import Optional
from flask import current_app from flask import current_app
from flask_mail import Message # type: ignore from flask_mail import Message # type: ignore
@ -13,13 +11,13 @@ class EmailService:
def add_email( def add_email(
subject: str, subject: str,
sender: str, sender: str,
recipients: List[str], recipients: list[str],
content: str, content: str,
content_html: str, content_html: str,
cc: Optional[str] = None, cc: str | None = None,
bcc: Optional[str] = None, bcc: str | None = None,
reply_to: Optional[str] = None, reply_to: str | None = None,
attachment_files: Optional[dict] = None, attachment_files: dict | None = None,
) -> None: ) -> None:
"""We will receive all data related to an email and send it.""" """We will receive all data related to an email and send it."""
mail = current_app.config["MAIL_APP"] mail = current_app.config["MAIL_APP"]

View File

@ -1,6 +1,5 @@
from flask import current_app from flask import current_app
from flask import g from flask import g
from spiffworkflow_backend.models.db import db from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.message_instance import MessageInstanceModel from spiffworkflow_backend.models.message_instance import MessageInstanceModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel from spiffworkflow_backend.models.process_instance import ProcessInstanceModel

View File

@ -1,14 +1,11 @@
"""File_system_service.""" """File_system_service."""
import os import os
from collections.abc import Generator
from contextlib import contextmanager from contextlib import contextmanager
from datetime import datetime from datetime import datetime
from typing import Generator
from typing import List
from typing import Optional
import pytz import pytz
from flask import current_app 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 CONTENT_TYPES
from spiffworkflow_backend.models.file import File from spiffworkflow_backend.models.file import File
@ -143,7 +140,7 @@ class FileSystemService:
return FileType[extension] return FileType[extension]
@staticmethod @staticmethod
def _get_files(file_path: str, file_name: Optional[str] = None) -> List[File]: def _get_files(file_path: str, file_name: str | None = 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 = [] files = []
items = os.scandir(file_path) items = os.scandir(file_path)

View File

@ -4,12 +4,9 @@ import re
import shutil import shutil
import subprocess # noqa we need the subprocess module to safely run the git commands import subprocess # noqa we need the subprocess module to safely run the git commands
import uuid import uuid
from typing import Optional
from typing import Union
from flask import current_app from flask import current_app
from flask import g from flask import g
from spiffworkflow_backend.config import ConfigurationError from spiffworkflow_backend.config import ConfigurationError
from spiffworkflow_backend.models.process_model import ProcessModelInfo from spiffworkflow_backend.models.process_model import ProcessModelInfo
from spiffworkflow_backend.services.file_system_service import FileSystemService from spiffworkflow_backend.services.file_system_service import FileSystemService
@ -48,7 +45,7 @@ class GitService:
cls, cls,
process_model: ProcessModelInfo, process_model: ProcessModelInfo,
revision: str, revision: str,
file_name: Optional[str] = None, file_name: str | None = None,
) -> str: ) -> str:
"""Get_instance_file_contents_for_revision.""" """Get_instance_file_contents_for_revision."""
bpmn_spec_absolute_dir = current_app.config["SPIFFWORKFLOW_BACKEND_BPMN_SPEC_ABSOLUTE_DIR"] bpmn_spec_absolute_dir = current_app.config["SPIFFWORKFLOW_BACKEND_BPMN_SPEC_ABSOLUTE_DIR"]
@ -68,8 +65,8 @@ class GitService:
def commit( def commit(
cls, cls,
message: str, message: str,
repo_path: Optional[str] = None, repo_path: str | None = None,
branch_name: Optional[str] = None, branch_name: str | None = None,
) -> str: ) -> str:
"""Commit.""" """Commit."""
cls.check_for_basic_configs() cls.check_for_basic_configs()
@ -134,7 +131,7 @@ class GitService:
@classmethod @classmethod
def run_shell_command( def run_shell_command(
cls, command: list[str], return_success_state: bool = False cls, command: list[str], return_success_state: bool = False
) -> Union[subprocess.CompletedProcess[bytes], bool]: ) -> subprocess.CompletedProcess[bytes] | bool:
"""Run_shell_command.""" """Run_shell_command."""
my_env = os.environ.copy() my_env = os.environ.copy()
my_env["GIT_COMMITTER_NAME"] = current_app.config.get("SPIFFWORKFLOW_BACKEND_GIT_USERNAME") or "unknown" my_env["GIT_COMMITTER_NAME"] = current_app.config.get("SPIFFWORKFLOW_BACKEND_GIT_USERNAME") or "unknown"
@ -179,8 +176,8 @@ class GitService:
valid_clone_urls = [repo["clone_url"], repo["git_url"], repo["ssh_url"]] valid_clone_urls = [repo["clone_url"], repo["git_url"], repo["ssh_url"]]
if config_clone_url not in valid_clone_urls: if config_clone_url not in valid_clone_urls:
raise GitCloneUrlMismatchError( raise GitCloneUrlMismatchError(
"Configured clone url does not match the repo URLs from webhook: %s =/= %s" f"Configured clone url does not match the repo URLs from webhook: {config_clone_url} =/="
% (config_clone_url, valid_clone_urls) f" {valid_clone_urls}"
) )
# Test webhook requests have a zen koan and hook info. # Test webhook requests have a zen koan and hook info.

Some files were not shown because too many files have changed in this diff Show More