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: "mypy" }
- { python: "3.10", os: "ubuntu-latest", session: "mypy" }
- { python: "3.9", os: "ubuntu-latest", session: "mypy" }
- {
python: "3.11",
os: "ubuntu-latest",
@ -44,12 +43,6 @@ jobs:
session: "tests",
database: "sqlite",
}
- {
python: "3.9",
os: "ubuntu-latest",
session: "tests",
database: "sqlite",
}
# 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.
# so ignore windows tests until we can get it fixed.

View File

@ -44,30 +44,13 @@ repos:
language: system
types: [text]
stages: [commit, push, manual]
- id: flake8
- id: ruff
files: ^spiffworkflow-backend/
name: flake8
entry: flake8
name: ruff
entry: ruff
language: system
types: [python]
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
files: ^spiffworkflow-backend/
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"
black = ">=21.10b0"
flake8-bandit = "^2.1.2"
ruff = "^0.0.270"
# 1.7.3 broke us. https://github.com/PyCQA/bandit/issues/841
bandit = "1.7.2"

View File

@ -28,27 +28,6 @@ repos:
language: system
types: [text]
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
name: Trim Trailing Whitespace
entry: trailing-whitespace-fixer

View File

@ -43,7 +43,7 @@ Request features on the `Issue Tracker`_.
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_
- Nox_

View File

@ -48,7 +48,7 @@ Running Locally
Requirements
------------
* Python 3.9+
* Python 3.10+
* 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 os
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.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.services.process_instance_processor import (
ProcessInstanceProcessor,
)
from spiffworkflow_backend.services.process_instance_service import (
ProcessInstanceService,
)
from spiffworkflow_backend.services.process_instance_processor import ProcessInstanceProcessor
from spiffworkflow_backend.services.process_instance_service import ProcessInstanceService
def main():

View File

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

View File

@ -4,14 +4,13 @@ import shutil
import pytest
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.db import db
from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.services.authorization_service import AuthorizationService
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
# otherwise typeguard cannot work. hence the noqa: E402

View File

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

View File

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

View File

@ -1,12 +1,12 @@
"""empty message
Revision ID: 0c7428378d6e
Revises:
Revises:
Create Date: 2023-04-20 14:05:44.779453
"""
from alembic import op
import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import mysql
# revision identifiers, used by Alembic.

View File

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

View File

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

View File

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

View File

@ -21,7 +21,7 @@ except ImportError:
package = "spiffworkflow_backend"
python_versions = ["3.11", "3.10", "3.9"]
python_versions = ["3.11", "3.10"]
nox.needs_version = ">= 2021.6.6"
nox.options.sessions = (
"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"
[tool.poetry.dependencies]
python = ">=3.9,<3.12"
python = ">=3.10,<3.12"
click = "^8.0.1"
flask = "2.2.2"
flask-admin = "*"
flask-bcrypt = "*"
flask-cors = "*"
flask-jwt-extended = "^4.4.4"
flask-mail = "*"
flask-marshmallow = "*"
flask-migrate = "*"
flask-restful = "*"
flask-simple-crypt = "^0.3.3"
werkzeug = "*"
SpiffWorkflow = {git = "https://github.com/sartography/SpiffWorkflow", rev = "main"}
# 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
# because if not then poetry export won't have them and nox -s mypy --pythons 3.10
# will fail
types-dateparser = "^1.1.4.1"
types-Werkzeug = "^1.0.9"
types-PyYAML = "^6.0.12"
types-Flask = "^1.1.6"
@ -74,14 +77,9 @@ sqlalchemy-stubs = { git = "https://github.com/burnettk/sqlalchemy-stubs.git", r
simplejson = "^3.17.6"
pytz = "^2022.6"
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"
prometheus-flask-exporter = "^0.22.3"
safety = "^2.3.5"
sqlalchemy = "^2.0.7"
marshmallow-sqlalchemy = "^0.29.0"
spiff-element-units = "^0.3.0"
@ -89,32 +87,20 @@ spiff-element-units = "^0.3.0"
[tool.poetry.dev-dependencies]
pytest = "^7.1.2"
coverage = {extras = ["toml"], version = "^6.1"}
safety = "^2.3.1"
safety = "^2.3.5"
mypy = ">=0.961"
typeguard = "^3"
xdoctest = {extras = ["colors"], version = "^1.0.1"}
# sphinx = "^5.0.2"
# sphinx-autobuild = ">=2021.3.14"
pre-commit = "^2.20.0"
flake8 = "^4.0.1"
black = ">=21.10b0"
flake8-bandit = "^2.1.2"
ruff = "^0.0.270"
# 1.7.3 broke us. https://github.com/PyCQA/bandit/issues/841
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"
pep8-naming = "^0.13.2"
darglint = "^1.8.1"
reorder-python-imports = "^3.9.0"
pre-commit-hooks = "^4.0.1"
# sphinx-click = "^4.3.0"
Pygments = "^2.10.0"
pyupgrade = "^3.1.0"
# furo = ">=2021.11.12"
[tool.poetry.scripts]
spiffworkflow-backend = "spiffworkflow_backend.__main__:main"
@ -170,12 +156,39 @@ implicit_reexport = true
namespace_packages = true
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]
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
# target python 3.10
target-version = "py310"
[tool.ruff.per-file-ignores]
"migrations/versions/*.py" = ["E501"]
[tool.ruff.isort]
force-single-line = true
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"

View File

@ -1,7 +1,7 @@
sonar.organization=sartography
sonar.projectKey=sartography_spiffworkflow-backend
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.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.models.db import db
from spiffworkflow_backend.models.db import migrate
from spiffworkflow_backend.routes.openid_blueprint.openid_blueprint import (
openid_blueprint,
)
from spiffworkflow_backend.routes.openid_blueprint.openid_blueprint import openid_blueprint
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_blueprint import user_blueprint
from spiffworkflow_backend.services.authorization_service import AuthorizationService
from spiffworkflow_backend.services.background_processing_service import (
BackgroundProcessingService,
)
from spiffworkflow_backend.services.background_processing_service import BackgroundProcessingService
class MyJSONEncoder(DefaultJSONProvider):

View File

@ -20,7 +20,6 @@ from SpiffWorkflow.exceptions import SpiffWorkflowException # type: ignore
from SpiffWorkflow.exceptions import WorkflowException
from SpiffWorkflow.specs.base import TaskSpec # type: ignore
from SpiffWorkflow.task import Task # type: ignore
from spiffworkflow_backend.models.task import TaskModel # noqa: F401
from spiffworkflow_backend.services.authentication_service import NotAuthorizedError
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 TaskService
api_error_blueprint = Blueprint("api_error_blueprint", __name__)

View File

@ -2,9 +2,8 @@
import time
import sqlalchemy
from sqlalchemy.sql import text
from spiffworkflow_backend.models.db import db
from sqlalchemy.sql import text
def try_to_connect(start_time: float) -> None:

View File

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

View File

@ -10,6 +10,9 @@ avoid circular imports
# unused imports are needed for SQLAlchemy to load the models
# 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
# must load these before UserModel and GroupModel for relationships

View File

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

View File

@ -6,8 +6,8 @@ from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship
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 db
class BpmnProcessNotFoundError(Exception):

View File

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

View File

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

View File

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

View File

@ -5,14 +5,13 @@ from typing import TYPE_CHECKING
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 db
if TYPE_CHECKING:
from spiffworkflow_backend.models.user_group_assignment import ( # noqa: F401
UserGroupAssignmentModel,
) # noqa: F401
# 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"

View File

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

View File

@ -6,8 +6,8 @@ from dataclasses import dataclass
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.human_task import HumanTaskModel
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.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 db
class JsonDataModelNotFoundError(Exception):

View File

@ -1,25 +1,24 @@
"""Message_instance."""
import enum
from dataclasses import dataclass
from typing import Any
from typing import Optional
from typing import TYPE_CHECKING
from typing import Any
from flask import current_app
from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine # type: ignore
from sqlalchemy import ForeignKey
from sqlalchemy.event import listens_for
from sqlalchemy.orm import relationship
from sqlalchemy.orm import Session
from sqlalchemy.orm import relationship
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 db
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.user import UserModel
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,
)
@ -151,7 +150,7 @@ class MessageInstanceModel(SpiffworkflowBaseDBModel):
@listens_for(Session, "before_flush") # type: ignore
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:
"""Ensure_failure_cause_is_set_if_message_instance_failed."""
for instance in session.new:

View File

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

View File

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

View File

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

View File

@ -1,12 +1,11 @@
"""PermissionTarget."""
import re
from dataclasses import dataclass
from typing import Optional
from sqlalchemy.orm import validates
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
class InvalidPermissionTargetUriError(Exception):
@ -24,7 +23,7 @@ class PermissionTargetModel(SpiffworkflowBaseDBModel):
id: int = db.Column(db.Integer, primary_key=True)
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__."""
if id:
self.id = id

View File

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

View File

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

View File

@ -8,8 +8,8 @@ from dataclasses import field
from typing import Any
import marshmallow
from marshmallow import post_load
from marshmallow import Schema
from marshmallow import post_load
from spiffworkflow_backend.interfaces import ProcessGroupLite
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.models.bpmn_process import BpmnProcessModel
from spiffworkflow_backend.models.bpmn_process_definition import (
BpmnProcessDefinitionModel,
)
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.bpmn_process_definition import BpmnProcessDefinitionModel
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 TaskSchema
from spiffworkflow_backend.models.user import UserModel

View File

@ -1,11 +1,10 @@
from dataclasses import dataclass
from typing import Optional
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
@dataclass
@ -19,9 +18,9 @@ class ProcessInstanceErrorDetailModel(SpiffworkflowBaseDBModel):
message: str = db.Column(db.String(1024), nullable=False)
# 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_offset: Optional[int] = db.Column(db.Integer)
task_line_contents: Optional[str] = db.Column(db.String(255))
task_trace: Optional[list] = db.Column(db.JSON)
task_line_number: int | None = db.Column(db.Integer)
task_offset: int | None = db.Column(db.Integer)
task_line_contents: str | None = db.Column(db.String(255))
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 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 db
from spiffworkflow_backend.models.user import UserModel

View File

@ -1,12 +1,11 @@
"""Process_instance_file_data."""
from dataclasses import dataclass
from typing import Optional
from sqlalchemy import ForeignKey
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 db
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
@ -19,7 +18,7 @@ class ProcessInstanceFileDataModel(SpiffworkflowBaseDBModel):
ForeignKey(ProcessInstanceModel.id), nullable=False, index=True # type: ignore
)
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)
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

View File

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

View File

@ -1,11 +1,10 @@
"""Process_instance_queue."""
from dataclasses import dataclass
from typing import Union
from sqlalchemy import ForeignKey
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
@ -21,8 +20,8 @@ class ProcessInstanceQueueModel(SpiffworkflowBaseDBModel):
)
run_at_in_seconds: 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_at_in_seconds: Union[int, None] = db.Column(db.Integer, index=True, nullable=True)
locked_by: str | None = db.Column(db.String(80), 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)
updated_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
if sys.version_info < (3, 11):
from typing_extensions import TypedDict, NotRequired
from typing_extensions import NotRequired
from typing_extensions import TypedDict
else:
from typing import TypedDict, NotRequired
from typing import NotRequired
from typing import TypedDict
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.json_data import JsonDataModel # noqa: F401
from spiffworkflow_backend.models.user import UserModel
@ -123,7 +125,7 @@ class ProcessInstanceReportModel(SpiffworkflowBaseDBModel):
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)
process_instance_report = cls(

View File

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

View File

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

View File

@ -4,8 +4,8 @@ from dataclasses import dataclass
from marshmallow import Schema
from sqlalchemy import ForeignKey
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
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 sqlalchemy import UniqueConstraint
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel
from spiffworkflow_backend.models.db import db
class SpecReferenceNotFoundError(Exception):

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,6 @@
"""APIs for dealing with process groups, process models, and process instances."""
import json
from typing import Any
from typing import Dict
import flask.wrappers
from flask import Blueprint
@ -13,14 +12,10 @@ from flask import request
from flask.wrappers import Response
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.exceptions.process_entity_not_found_error import (
ProcessEntityNotFoundError,
)
from spiffworkflow_backend.exceptions.process_entity_not_found_error import ProcessEntityNotFoundError
from spiffworkflow_backend.models.principal import PrincipalModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.process_instance_file_data import (
ProcessInstanceFileDataModel,
)
from spiffworkflow_backend.models.process_instance_file_data import ProcessInstanceFileDataModel
from spiffworkflow_backend.models.process_model import ProcessModelInfo
from spiffworkflow_backend.models.spec_reference import SpecReferenceCache
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.git_service import GitService
from spiffworkflow_backend.services.process_caller_service import ProcessCallerService
from spiffworkflow_backend.services.process_instance_processor import (
ProcessInstanceProcessor,
)
from spiffworkflow_backend.services.process_instance_processor import ProcessInstanceProcessor
from spiffworkflow_backend.services.process_model_service import ProcessModelService
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."""
if "requests_to_check" not in body:
raise (
@ -162,7 +154,7 @@ def process_data_file_download(
# "full_name": "sartography/sample-process-models", "private": False .... }}
# test with: ngrok http 7000
# 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."""
auth_header = request.headers.get("X-Hub-Signature-256")
AuthorizationService.verify_sha256_token(auth_header)

View File

@ -1,7 +1,6 @@
"""APIs for dealing with process groups, process models, and process instances."""
import json
from typing import Any
from typing import Optional
import flask.wrappers
from flask import g
@ -10,19 +9,13 @@ from flask import make_response
from flask.wrappers import Response
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.exceptions.process_entity_not_found_error import (
ProcessEntityNotFoundError,
)
from spiffworkflow_backend.exceptions.process_entity_not_found_error import ProcessEntityNotFoundError
from spiffworkflow_backend.models.process_group import ProcessGroup
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 (
_un_modify_modified_process_model_id,
)
from spiffworkflow_backend.routes.process_api_blueprint import _un_modify_modified_process_model_id
from spiffworkflow_backend.services.process_model_service import ProcessModelService
from spiffworkflow_backend.services.process_model_service import (
ProcessModelWithInstancesNotDeletableError,
)
from spiffworkflow_backend.services.process_model_service import ProcessModelWithInstancesNotDeletableError
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(
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:
process_groups = ProcessModelService.get_process_groups_for_api(process_group_identifier)
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
from flask import jsonify
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_definition import TaskDefinitionModel
from spiffworkflow_backend.models.user import UserModel
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
def log_list(
@ -25,10 +20,10 @@ def log_list(
page: int = 1,
per_page: int = 100,
events: bool = False,
bpmn_name: Optional[str] = None,
bpmn_identifier: Optional[str] = None,
task_type: Optional[str] = None,
event_type: Optional[str] = None,
bpmn_name: str | None = None,
bpmn_identifier: str | None = None,
task_type: str | None = None,
event_type: str | None = None,
) -> flask.wrappers.Response:
# to make sure the process instance exists
process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
@ -91,7 +86,7 @@ def log_list(
def typeahead_filter_values(
modified_process_model_identifier: str,
process_instance_id: int,
task_type: Optional[str] = None,
task_type: str | None = None,
) -> flask.wrappers.Response:
process_instance = _find_process_instance_by_id_or_raise(process_instance_id)
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_definitions = task_definition_query.all()
task_bpmn_names: Set[str] = set()
task_bpmn_identifiers: Set[str] = set()
task_bpmn_names: set[str] = set()
task_bpmn_identifiers: set[str] = set()
for task_definition in task_definitions:
# not checking for None so we also exclude empty strings
if task_definition.bpmn_name:

View File

@ -1,9 +1,6 @@
"""APIs for dealing with process groups, process models, and process instances."""
import json
from typing import Any
from typing import Dict
from typing import Optional
from typing import Union
import flask.wrappers
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.models.bpmn_process import BpmnProcessModel
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.human_task import HumanTaskModel
from spiffworkflow_backend.models.human_task_user import HumanTaskUserModel
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 (
ProcessInstanceCannotBeDeletedError,
)
from spiffworkflow_backend.models.process_instance import ProcessInstanceCannotBeDeletedError
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceModelSchema
from spiffworkflow_backend.models.process_instance_metadata import (
ProcessInstanceMetadataModel,
)
from spiffworkflow_backend.models.process_instance_queue import (
ProcessInstanceQueueModel,
)
from spiffworkflow_backend.models.process_instance_metadata import ProcessInstanceMetadataModel
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 Report
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.task import TaskModel
from spiffworkflow_backend.models.task_definition import TaskDefinitionModel
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 (
_un_modify_modified_process_model_id,
)
from spiffworkflow_backend.routes.process_api_blueprint import _un_modify_modified_process_model_id
from spiffworkflow_backend.services.authorization_service import AuthorizationService
from spiffworkflow_backend.services.error_handling_service import ErrorHandlingService
from spiffworkflow_backend.services.git_service import GitCommandError
from spiffworkflow_backend.services.git_service import GitService
from spiffworkflow_backend.services.message_service import MessageService
from spiffworkflow_backend.services.process_instance_processor import (
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 (
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_instance_processor import 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 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.spec_file_service import SpecFileService
from spiffworkflow_backend.services.task_service import TaskService
@ -227,8 +200,8 @@ def process_instance_resume(
def process_instance_list_for_me(
body: Dict[str, Any],
process_model_identifier: Optional[str] = None,
body: dict[str, Any],
process_model_identifier: str | None = None,
page: int = 1,
per_page: int = 100,
) -> flask.wrappers.Response:
@ -244,8 +217,8 @@ def process_instance_list_for_me(
def process_instance_list(
body: Dict[str, Any],
process_model_identifier: Optional[str] = None,
body: dict[str, Any],
process_model_identifier: str | None = None,
page: int = 1,
per_page: int = 100,
) -> flask.wrappers.Response:
@ -264,9 +237,9 @@ def process_instance_list(
def process_instance_report_show(
report_hash: Optional[str] = None,
report_id: Optional[int] = None,
report_identifier: Optional[str] = None,
report_hash: str | None = None,
report_id: int | None = None,
report_identifier: str | None = None,
) -> flask.wrappers.Response:
if report_hash is None and report_id is None and report_identifier is None:
raise ApiError(
@ -276,7 +249,7 @@ def process_instance_report_show(
" report_identifier."
),
)
response_result: Optional[Union[Report, ProcessInstanceReportModel]] = None
response_result: Report | ProcessInstanceReportModel | None = None
if report_hash is not None:
json_data = JsonDataModel.query.filter_by(hash=report_hash).first()
if json_data is None:
@ -297,7 +270,7 @@ def process_instance_report_show(
def process_instance_report_column_list(
process_model_identifier: Optional[str] = None,
process_model_identifier: str | None = None,
) -> flask.wrappers.Response:
table_columns = ProcessInstanceReportService.builtin_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(
modified_process_model_identifier: str,
process_instance_id: int,
process_identifier: Optional[str] = None,
process_identifier: str | None = None,
) -> flask.wrappers.Response:
"""Process_instance_show_for_me."""
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(
modified_process_model_identifier: str,
process_instance_id: int,
process_identifier: Optional[str] = None,
process_identifier: str | None = None,
) -> flask.wrappers.Response:
"""Create_process_instance."""
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)
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(
identifier=body["identifier"],
user=g.user,
@ -387,7 +360,7 @@ def process_instance_report_create(body: Dict[str, Any]) -> flask.wrappers.Respo
def process_instance_report_update(
report_id: int,
body: Dict[str, Any],
body: dict[str, Any],
) -> flask.wrappers.Response:
"""Process_instance_report_update."""
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,
process_instance_id: int,
most_recent_tasks_only: bool = False,
bpmn_process_guid: Optional[str] = None,
to_task_guid: Optional[str] = None,
bpmn_process_guid: str | None = None,
to_task_guid: str | None = None,
) -> flask.wrappers.Response:
"""Process_instance_task_list_without_task_data_for_me."""
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,
process_instance_id: int,
most_recent_tasks_only: bool = False,
bpmn_process_guid: Optional[str] = None,
to_task_guid: Optional[str] = None,
bpmn_process_guid: str | None = None,
to_task_guid: str | None = None,
) -> flask.wrappers.Response:
"""Process_instance_task_list_without_task_data."""
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(
_modified_process_model_identifier: str,
process_instance: ProcessInstanceModel,
bpmn_process_guid: Optional[str] = None,
to_task_guid: Optional[str] = None,
bpmn_process_guid: str | None = None,
to_task_guid: str | None = None,
most_recent_tasks_only: bool = False,
) -> flask.wrappers.Response:
"""Process_instance_task_list."""
@ -482,7 +455,7 @@ def process_instance_task_list(
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] = []
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()
@ -645,7 +618,7 @@ def process_instance_find_by_id(
def send_user_signal_event(
process_instance_id: int,
body: Dict,
body: dict,
) -> Response:
"""Send a user signal event to a process instance."""
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(
modified_process_model_identifier: str,
process_instance_id: int,
body: Dict,
body: dict,
) -> Response:
"""Send a bpmn event to a process instance."""
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(
modified_process_model_identifier: str,
process_instance: ProcessInstanceModel,
process_identifier: Optional[str] = None,
process_identifier: str | None = None,
) -> flask.wrappers.Response:
"""_get_process_instance."""
process_model_identifier = modified_process_model_identifier.replace(":", "/")
@ -725,7 +698,7 @@ def _find_process_instance_for_me_or_raise(
process_instance_id: int,
) -> ProcessInstanceModel:
"""_find_process_instance_for_me_or_raise."""
process_instance: Optional[ProcessInstanceModel] = (
process_instance: ProcessInstanceModel | None = (
ProcessInstanceModel.query.filter_by(id=process_instance_id)
.outerjoin(HumanTaskModel)
.outerjoin(

View File

@ -4,9 +4,6 @@ import os
import re
from hashlib import sha256
from typing import Any
from typing import Dict
from typing import Optional
from typing import Union
import connexion # type: ignore
import flask.wrappers
@ -20,39 +17,27 @@ from werkzeug.datastructures import FileStorage
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.interfaces import IdToProcessGroupMapping
from spiffworkflow_backend.models.process_group import ProcessGroup
from spiffworkflow_backend.models.process_instance_report import (
ProcessInstanceReportModel,
)
from spiffworkflow_backend.models.process_instance_report import ProcessInstanceReportModel
from spiffworkflow_backend.models.process_model import ProcessModelInfo
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 _get_process_model
from spiffworkflow_backend.routes.process_api_blueprint import (
_un_modify_modified_process_model_id,
)
from spiffworkflow_backend.routes.process_api_blueprint import _un_modify_modified_process_model_id
from spiffworkflow_backend.services.file_system_service import FileSystemService
from spiffworkflow_backend.services.git_service import GitCommandError
from spiffworkflow_backend.services.git_service import GitService
from spiffworkflow_backend.services.git_service import MissingGitConfigsError
from spiffworkflow_backend.services.process_instance_report_service import (
ProcessInstanceReportNotFoundError,
)
from spiffworkflow_backend.services.process_instance_report_service import (
ProcessInstanceReportService,
)
from spiffworkflow_backend.services.process_instance_report_service import ProcessInstanceReportNotFoundError
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 (
ProcessModelWithInstancesNotDeletableError,
)
from spiffworkflow_backend.services.process_model_service import ProcessModelWithInstancesNotDeletableError
from spiffworkflow_backend.services.process_model_test_runner_service import ProcessModelTestRunner
from spiffworkflow_backend.services.spec_file_service import (
ProcessModelFileInvalidError,
)
from spiffworkflow_backend.services.spec_file_service import ProcessModelFileInvalidError
from spiffworkflow_backend.services.spec_file_service import SpecFileService
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:
"""Process_model_create."""
body_include_list = [
@ -120,7 +105,7 @@ def process_model_delete(
def process_model_update(
modified_process_model_identifier: str,
body: Dict[str, Union[str, bool, int, None, list]],
body: dict[str, str | bool | int | None | list],
) -> Any:
"""Process_model_update."""
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(
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:
"""Process_model_publish."""
if branch_to_update is None:
@ -209,10 +194,10 @@ def process_model_publish(
def process_model_list(
process_group_identifier: Optional[str] = None,
recursive: Optional[bool] = False,
filter_runnable_by_user: Optional[bool] = False,
include_parent_groups: Optional[bool] = False,
process_group_identifier: str | None = None,
recursive: bool | None = False,
filter_runnable_by_user: bool | None = False,
include_parent_groups: bool | None = False,
page: int = 1,
per_page: int = 100,
) -> 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(
modified_process_model_identifier: str,
test_case_file: Optional[str] = None,
test_case_identifier: Optional[str] = None,
test_case_file: str | None = None,
test_case_identifier: str | None = None,
) -> flask.wrappers.Response:
process_model_identifier = modified_process_model_identifier.replace(":", "/")
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"
# }
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:
"""Process_model_create_with_natural_language."""
pattern = re.compile(
@ -464,7 +449,7 @@ def process_model_create_with_natural_language(
def _get_file_from_request() -> FileStorage:
"""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:
raise ApiError(
error_code="no_file_given",
@ -503,7 +488,7 @@ def _create_or_update_process_model_file(
modified_process_model_identifier: str,
message_for_git_commit: str,
http_status_to_return: int,
file_contents_hash: Optional[str] = None,
file_contents_hash: str | None = None,
) -> flask.wrappers.Response:
"""_create_or_update_process_model_file."""
process_model_identifier = modified_process_model_identifier.replace(":", "/")

View File

@ -2,8 +2,6 @@
import json
import random
import string
from typing import Dict
from typing import Union
import flask.wrappers
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.routes.process_api_blueprint import _get_process_model
from spiffworkflow_backend.routes.process_api_blueprint import (
_get_required_parameter_or_raise,
)
from spiffworkflow_backend.routes.process_api_blueprint import _get_required_parameter_or_raise
from spiffworkflow_backend.services.script_unit_test_runner import ScriptUnitTestRunner
from spiffworkflow_backend.services.spec_file_service import SpecFileService
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:
"""Script_unit_test_create."""
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(
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:
"""Script_unit_test_run."""
# 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."""
import json
from typing import Dict
from flask import g
from flask import jsonify
@ -44,7 +43,7 @@ def secret_list(
return make_response(jsonify(response_json), 200)
def secret_create(body: Dict) -> Response:
def secret_create(body: dict) -> Response:
"""Add secret."""
secret_model = SecretService().add_secret(body["key"], body["value"], g.user.id)
return Response(

View File

@ -2,13 +2,10 @@
import json
import os
import uuid
from collections.abc import Generator
from sys import exc_info
from typing import Any
from typing import Dict
from typing import Generator
from typing import Optional
from typing import TypedDict
from typing import Union
import flask.wrappers
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 ProcessInstanceModelSchema
from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus
from spiffworkflow_backend.models.process_instance import (
ProcessInstanceTaskDataCannotBeUpdatedError,
)
from spiffworkflow_backend.models.process_instance import ProcessInstanceTaskDataCannotBeUpdatedError
from spiffworkflow_backend.models.process_instance_event import ProcessInstanceEventType
from spiffworkflow_backend.models.process_model import ProcessModelInfo
from spiffworkflow_backend.models.task import Task
from spiffworkflow_backend.models.task import TaskModel
from spiffworkflow_backend.models.user import UserModel
from spiffworkflow_backend.routes.process_api_blueprint import (
_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_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 _get_process_model
from spiffworkflow_backend.services.authorization_service import AuthorizationService
from spiffworkflow_backend.services.authorization_service import HumanTaskNotFoundError
from spiffworkflow_backend.services.authorization_service import UserDoesNotHaveAccessToTaskError
from spiffworkflow_backend.services.file_system_service import FileSystemService
from spiffworkflow_backend.services.process_instance_processor import (
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_processor import 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_tmp_service import ProcessInstanceTmpService
from spiffworkflow_backend.services.process_model_service import ProcessModelService
from spiffworkflow_backend.services.spec_file_service import SpecFileService
@ -91,7 +76,7 @@ class ReactJsonSchemaSelectOption(TypedDict):
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:
"""Task_list_my_tasks."""
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(
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:
"""Task_list_for_my_groups."""
return _get_tasks(
@ -197,7 +182,7 @@ def task_data_update(
process_instance_id: str,
modified_process_model_identifier: str,
task_guid: str,
body: Dict,
body: dict,
) -> Response:
"""Update task data."""
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,
process_instance_id: str,
task_guid: str,
body: Dict,
body: dict,
) -> Response:
"""Mark a task complete without executing it."""
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)
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."""
if extensions is None:
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 ""
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:
return processor.bpmn_process_instance.get_tasks(
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)
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[return_type] = entity
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]))
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)
# 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(
process_instance_id: int,
task_guid: str,
body: Dict[str, Any],
body: dict[str, Any],
save_as_draft: bool = False,
) -> flask.wrappers.Response:
principal = _find_principal_or_raise()
@ -586,7 +571,7 @@ def _task_submit_shared(
def task_submit(
process_instance_id: int,
task_guid: str,
body: Dict[str, Any],
body: dict[str, Any],
save_as_draft: bool = False,
) -> flask.wrappers.Response:
"""Task_submit_user_data."""
@ -599,7 +584,7 @@ def _get_tasks(
has_lane_assignment_id: bool = True,
page: int = 1,
per_page: int = 100,
user_group_identifier: Optional[str] = None,
user_group_identifier: str | None = None,
) -> flask.wrappers.Response:
"""Get_tasks."""
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(
task_guid: str,
process_instance: ProcessInstanceModel,
processor: Union[ProcessInstanceProcessor, None] = None,
processor: ProcessInstanceProcessor | None = None,
) -> SpiffTask:
"""Get_spiff_task_from_process_instance."""
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:
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
).first()
if task_model is None:

View File

@ -4,8 +4,6 @@ import base64
import json
import re
from typing import Any
from typing import Dict
from typing import Optional
import flask
import jwt
@ -20,14 +18,12 @@ from werkzeug.wrappers import Response
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.helpers.api_version import V1_API_PATH_PREFIX
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.models.group import GroupModel
from spiffworkflow_backend.models.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 UserModel
from spiffworkflow_backend.services.authentication_service import AuthenticationService
from spiffworkflow_backend.services.authentication_service import (
MissingAccessTokenError,
)
from spiffworkflow_backend.services.authentication_service import MissingAccessTokenError
from spiffworkflow_backend.services.authentication_service import TokenExpiredError
from spiffworkflow_backend.services.authorization_service import AuthorizationService
from spiffworkflow_backend.services.group_service import GroupService
@ -40,7 +36,7 @@ from spiffworkflow_backend.services.user_service import UserService
# 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).
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.
"""
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?:\/\/",
"",
current_app.config["SPIFFWORKFLOW_BACKEND_URL_FOR_FRONTEND"],
@ -247,7 +243,7 @@ def parse_id_token(token: str) -> Any:
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_redirect_url = state_dict["redirect_url"]
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
def logout(id_token: str, redirect_url: Optional[str]) -> Response:
def logout(id_token: str, redirect_url: str | None) -> Response:
"""Logout."""
if redirect_url is None:
redirect_url = ""
@ -335,7 +331,7 @@ def logout_return() -> Response:
return redirect(f"{frontend_url}/")
def get_decoded_token(token: str) -> Optional[Dict]:
def get_decoded_token(token: str) -> dict | None:
"""Get_token_type."""
try:
decoded_token = jwt.decode(token, options={"verify_signature": False})
@ -361,7 +357,7 @@ def get_scope(token: str) -> str:
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."""
sub = decoded_token["sub"]
parts = sub.split("::")

View File

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

View File

@ -1,6 +1,5 @@
"""Users_controller."""
from typing import Any
from typing import Dict
import flask
from flask import current_app
@ -12,7 +11,7 @@ from spiffworkflow_backend.exceptions.api_error import ApiError
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:
raise ApiError(
error_code="username_not_given",

View File

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

View File

@ -1,9 +1,7 @@
"""Fact_service."""
from typing import Any
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

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_target import PermissionTargetModel
from spiffworkflow_backend.models.principal import PrincipalModel
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

View File

@ -3,10 +3,7 @@ from typing import Any
from flask import current_app
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

View File

@ -1,13 +1,9 @@
"""Get_data_sizes."""
from typing import Any
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.services.process_instance_processor import (
ProcessInstanceProcessor,
)
from spiffworkflow_backend.services.process_instance_processor import ProcessInstanceProcessor
class TaskNotGivenToScriptError(Exception):

View File

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

View File

@ -1,9 +1,7 @@
"""Get_env."""
from typing import Any
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

View File

@ -2,10 +2,7 @@
from typing import Any
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

View File

@ -3,9 +3,7 @@ from typing import Any
from spiffworkflow_backend.models.group import GroupModel
from spiffworkflow_backend.models.group import GroupNotFoundError
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

View File

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

View File

@ -3,11 +3,8 @@ from datetime import datetime
from typing import Any
import pytz
from spiffworkflow_backend.exceptions.api_error import ApiError
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

View File

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

View File

@ -1,9 +1,7 @@
"""Get_secret."""
from typing import Any
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.services.secret_service import SecretService

View File

@ -1,9 +1,7 @@
"""Get_process_info."""
from typing import Any
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

View File

@ -2,11 +2,8 @@
from typing import Any
from flask import current_app
from spiffworkflow_backend.models.process_model import ProcessModelInfo
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

View File

@ -1,9 +1,7 @@
"""Get_env."""
from typing import Any
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.services.authorization_service import AuthorizationService

View File

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

View File

@ -2,14 +2,12 @@
import time
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.process_instance import ProcessInstanceModel
from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus
from spiffworkflow_backend.services.process_instance_service import (
ProcessInstanceService,
)
from spiffworkflow_backend.services.process_instance_service import ProcessInstanceService
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
def load_acceptance_test_fixtures() -> list[ProcessInstanceModel]:

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,5 @@
"""Data_setup_service."""
from flask import current_app
from spiffworkflow_backend.models.db import db
from spiffworkflow_backend.services.process_model_service import ProcessModelService
from spiffworkflow_backend.services.spec_file_service import SpecFileService

View File

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

View File

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

View File

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

View File

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

View File

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