Squashed 'spiffworkflow-backend/' changes from ffb6d366..d0336039
d0336039 added api endpoint to get the auth list from connector proxy w/ burnettk ca13f0ca Merge pull request #142 from sartography/bugfix/clean_up_non_existant_workflow_types_and_libraries 304ee66b lint 935c883b migration. 1f99264c Remove all references to the MasterWorkflow, standalone workflows, and libraries, as these concepts should no longer exist. a7a83a97 Merge branch 'main' of github.com:sartography/spiffworkflow-backend 6ce1cdb0 updated flask-bpmn for new ApiError. w/ burnettk 796735e8 Merge pull request #141 from sartography/bugfix/allow-strptime-in-scripts 5e13a239 Remove the "master_spec" 7e52204f fix bs issue 8cc59eb3 add strptime to script engine git-subtree-dir: spiffworkflow-backend git-subtree-split: d0336039c556bf5f19f8db2f32d9b37228e9f057
This commit is contained in:
parent
aa22f4b397
commit
64e7049c9a
|
@ -1,8 +1,8 @@
|
||||||
"""empty message
|
"""empty message
|
||||||
|
|
||||||
Revision ID: 07ff3fbef405
|
Revision ID: b41f0d35641a
|
||||||
Revises:
|
Revises:
|
||||||
Create Date: 2022-10-13 07:56:01.234090
|
Create Date: 2022-10-18 16:16:23.575571
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
|
@ -10,7 +10,7 @@ import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
# revision identifiers, used by Alembic.
|
||||||
revision = '07ff3fbef405'
|
revision = 'b41f0d35641a'
|
||||||
down_revision = None
|
down_revision = None
|
||||||
branch_labels = None
|
branch_labels = None
|
||||||
depends_on = None
|
depends_on = None
|
|
@ -95,7 +95,7 @@ python-versions = ">=3.5"
|
||||||
dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"]
|
dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"]
|
||||||
docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"]
|
docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"]
|
||||||
tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"]
|
tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"]
|
||||||
tests_no_zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"]
|
tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "Babel"
|
name = "Babel"
|
||||||
|
@ -268,7 +268,7 @@ optional = false
|
||||||
python-versions = ">=3.6.0"
|
python-versions = ">=3.6.0"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
unicode_backport = ["unicodedata2"]
|
unicode-backport = ["unicodedata2"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "classify-imports"
|
name = "classify-imports"
|
||||||
|
@ -639,7 +639,7 @@ werkzeug = "*"
|
||||||
type = "git"
|
type = "git"
|
||||||
url = "https://github.com/sartography/flask-bpmn"
|
url = "https://github.com/sartography/flask-bpmn"
|
||||||
reference = "main"
|
reference = "main"
|
||||||
resolved_reference = "f3fc539423a3522d142146d2a039c0cd49badaf5"
|
resolved_reference = "42cebab51fe469ab9dcb45672917d34c1f30987a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "Flask-Cors"
|
name = "Flask-Cors"
|
||||||
|
@ -1512,7 +1512,7 @@ urllib3 = ">=1.21.1,<1.27"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
|
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
|
||||||
use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"]
|
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "requests-toolbelt"
|
name = "requests-toolbelt"
|
||||||
|
@ -1625,7 +1625,7 @@ falcon = ["falcon (>=1.4)"]
|
||||||
fastapi = ["fastapi (>=0.79.0)"]
|
fastapi = ["fastapi (>=0.79.0)"]
|
||||||
flask = ["blinker (>=1.1)", "flask (>=0.11)"]
|
flask = ["blinker (>=1.1)", "flask (>=0.11)"]
|
||||||
httpx = ["httpx (>=0.16.0)"]
|
httpx = ["httpx (>=0.16.0)"]
|
||||||
pure_eval = ["asttokens", "executing", "pure-eval"]
|
pure-eval = ["asttokens", "executing", "pure-eval"]
|
||||||
pyspark = ["pyspark (>=2.4.4)"]
|
pyspark = ["pyspark (>=2.4.4)"]
|
||||||
quart = ["blinker (>=1.1)", "quart (>=0.16.1)"]
|
quart = ["blinker (>=1.1)", "quart (>=0.16.1)"]
|
||||||
rq = ["rq (>=0.6)"]
|
rq = ["rq (>=0.6)"]
|
||||||
|
@ -1884,19 +1884,19 @@ aiomysql = ["aiomysql", "greenlet (!=0.4.17)"]
|
||||||
aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"]
|
aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"]
|
||||||
asyncio = ["greenlet (!=0.4.17)"]
|
asyncio = ["greenlet (!=0.4.17)"]
|
||||||
asyncmy = ["asyncmy (>=0.2.3,!=0.2.4)", "greenlet (!=0.4.17)"]
|
asyncmy = ["asyncmy (>=0.2.3,!=0.2.4)", "greenlet (!=0.4.17)"]
|
||||||
mariadb_connector = ["mariadb (>=1.0.1,!=1.1.2)"]
|
mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2)"]
|
||||||
mssql = ["pyodbc"]
|
mssql = ["pyodbc"]
|
||||||
mssql_pymssql = ["pymssql"]
|
mssql-pymssql = ["pymssql"]
|
||||||
mssql_pyodbc = ["pyodbc"]
|
mssql-pyodbc = ["pyodbc"]
|
||||||
mypy = ["mypy (>=0.910)", "sqlalchemy2-stubs"]
|
mypy = ["mypy (>=0.910)", "sqlalchemy2-stubs"]
|
||||||
mysql = ["mysqlclient (>=1.4.0)", "mysqlclient (>=1.4.0,<2)"]
|
mysql = ["mysqlclient (>=1.4.0)", "mysqlclient (>=1.4.0,<2)"]
|
||||||
mysql_connector = ["mysql-connector-python"]
|
mysql-connector = ["mysql-connector-python"]
|
||||||
oracle = ["cx_oracle (>=7)", "cx_oracle (>=7,<8)"]
|
oracle = ["cx_oracle (>=7)", "cx_oracle (>=7,<8)"]
|
||||||
postgresql = ["psycopg2 (>=2.7)"]
|
postgresql = ["psycopg2 (>=2.7)"]
|
||||||
postgresql_asyncpg = ["asyncpg", "greenlet (!=0.4.17)"]
|
postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"]
|
||||||
postgresql_pg8000 = ["pg8000 (>=1.16.6,!=1.29.0)"]
|
postgresql-pg8000 = ["pg8000 (>=1.16.6,!=1.29.0)"]
|
||||||
postgresql_psycopg2binary = ["psycopg2-binary"]
|
postgresql-psycopg2binary = ["psycopg2-binary"]
|
||||||
postgresql_psycopg2cffi = ["psycopg2cffi"]
|
postgresql-psycopg2cffi = ["psycopg2cffi"]
|
||||||
pymysql = ["pymysql", "pymysql (<1)"]
|
pymysql = ["pymysql", "pymysql (<1)"]
|
||||||
sqlcipher = ["sqlcipher3_binary"]
|
sqlcipher = ["sqlcipher3_binary"]
|
||||||
|
|
||||||
|
@ -1982,7 +1982,7 @@ test = ["mypy", "pytest", "typing-extensions"]
|
||||||
name = "types-click"
|
name = "types-click"
|
||||||
version = "7.1.8"
|
version = "7.1.8"
|
||||||
description = "Typing stubs for click"
|
description = "Typing stubs for click"
|
||||||
category = "main"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
|
|
||||||
|
@ -1990,7 +1990,7 @@ python-versions = "*"
|
||||||
name = "types-Flask"
|
name = "types-Flask"
|
||||||
version = "1.1.6"
|
version = "1.1.6"
|
||||||
description = "Typing stubs for Flask"
|
description = "Typing stubs for Flask"
|
||||||
category = "main"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
|
|
||||||
|
@ -2003,7 +2003,7 @@ types-Werkzeug = "*"
|
||||||
name = "types-Jinja2"
|
name = "types-Jinja2"
|
||||||
version = "2.11.9"
|
version = "2.11.9"
|
||||||
description = "Typing stubs for Jinja2"
|
description = "Typing stubs for Jinja2"
|
||||||
category = "main"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
|
|
||||||
|
@ -2014,7 +2014,7 @@ types-MarkupSafe = "*"
|
||||||
name = "types-MarkupSafe"
|
name = "types-MarkupSafe"
|
||||||
version = "1.1.10"
|
version = "1.1.10"
|
||||||
description = "Typing stubs for MarkupSafe"
|
description = "Typing stubs for MarkupSafe"
|
||||||
category = "main"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
|
|
||||||
|
@ -2022,7 +2022,7 @@ python-versions = "*"
|
||||||
name = "types-pytz"
|
name = "types-pytz"
|
||||||
version = "2022.4.0.0"
|
version = "2022.4.0.0"
|
||||||
description = "Typing stubs for pytz"
|
description = "Typing stubs for pytz"
|
||||||
category = "main"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
|
|
||||||
|
@ -2030,7 +2030,7 @@ python-versions = "*"
|
||||||
name = "types-PyYAML"
|
name = "types-PyYAML"
|
||||||
version = "6.0.12"
|
version = "6.0.12"
|
||||||
description = "Typing stubs for PyYAML"
|
description = "Typing stubs for PyYAML"
|
||||||
category = "main"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
|
|
||||||
|
@ -2038,7 +2038,7 @@ python-versions = "*"
|
||||||
name = "types-requests"
|
name = "types-requests"
|
||||||
version = "2.28.11.1"
|
version = "2.28.11.1"
|
||||||
description = "Typing stubs for requests"
|
description = "Typing stubs for requests"
|
||||||
category = "main"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
|
|
||||||
|
@ -2049,7 +2049,7 @@ types-urllib3 = "<1.27"
|
||||||
name = "types-urllib3"
|
name = "types-urllib3"
|
||||||
version = "1.26.25"
|
version = "1.26.25"
|
||||||
description = "Typing stubs for urllib3"
|
description = "Typing stubs for urllib3"
|
||||||
category = "main"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
|
|
||||||
|
@ -2057,7 +2057,7 @@ python-versions = "*"
|
||||||
name = "types-Werkzeug"
|
name = "types-Werkzeug"
|
||||||
version = "1.0.9"
|
version = "1.0.9"
|
||||||
description = "Typing stubs for Werkzeug"
|
description = "Typing stubs for Werkzeug"
|
||||||
category = "main"
|
category = "dev"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
|
|
||||||
|
@ -2234,7 +2234,7 @@ testing = ["func-timeout", "jaraco.itertools", "pytest (>=6)", "pytest-black (>=
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "1.1"
|
lock-version = "1.1"
|
||||||
python-versions = ">=3.9,<3.11"
|
python-versions = ">=3.9,<3.11"
|
||||||
content-hash = "80df3106c84ea30cfbad3e6d708e136e07b6390c4d0c622aced0abf052d11300"
|
content-hash = "cff4bcfd10157833f1a0f0bb806c3543267c3e99cc13f311b328d101c30ac553"
|
||||||
|
|
||||||
[metadata.files]
|
[metadata.files]
|
||||||
alabaster = [
|
alabaster = [
|
||||||
|
@ -3013,18 +3013,7 @@ py = [
|
||||||
{file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
|
{file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
|
||||||
]
|
]
|
||||||
pyasn1 = [
|
pyasn1 = [
|
||||||
{file = "pyasn1-0.4.8-py2.4.egg", hash = "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3"},
|
|
||||||
{file = "pyasn1-0.4.8-py2.5.egg", hash = "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf"},
|
|
||||||
{file = "pyasn1-0.4.8-py2.6.egg", hash = "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00"},
|
|
||||||
{file = "pyasn1-0.4.8-py2.7.egg", hash = "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8"},
|
|
||||||
{file = "pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"},
|
{file = "pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"},
|
||||||
{file = "pyasn1-0.4.8-py3.1.egg", hash = "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86"},
|
|
||||||
{file = "pyasn1-0.4.8-py3.2.egg", hash = "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7"},
|
|
||||||
{file = "pyasn1-0.4.8-py3.3.egg", hash = "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576"},
|
|
||||||
{file = "pyasn1-0.4.8-py3.4.egg", hash = "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12"},
|
|
||||||
{file = "pyasn1-0.4.8-py3.5.egg", hash = "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2"},
|
|
||||||
{file = "pyasn1-0.4.8-py3.6.egg", hash = "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359"},
|
|
||||||
{file = "pyasn1-0.4.8-py3.7.egg", hash = "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776"},
|
|
||||||
{file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"},
|
{file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"},
|
||||||
]
|
]
|
||||||
pycodestyle = [
|
pycodestyle = [
|
||||||
|
|
|
@ -937,6 +937,20 @@ paths:
|
||||||
schema:
|
schema:
|
||||||
$ref: "#/components/schemas/ServiceTask"
|
$ref: "#/components/schemas/ServiceTask"
|
||||||
|
|
||||||
|
/authentications:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- Authentications
|
||||||
|
operationId: spiffworkflow_backend.routes.process_api_blueprint.authentication_list
|
||||||
|
summary: Gets all available authentications from connector proxy
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: All authentications
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/ServiceTask"
|
||||||
|
|
||||||
/tasks/{process_instance_id}/{task_id}:
|
/tasks/{process_instance_id}/{task_id}:
|
||||||
parameters:
|
parameters:
|
||||||
- name: task_id
|
- name: task_id
|
||||||
|
|
|
@ -22,6 +22,10 @@ SPIFFWORKFLOW_FRONTEND_URL = environ.get(
|
||||||
SPIFFWORKFLOW_BACKEND_URL = environ.get(
|
SPIFFWORKFLOW_BACKEND_URL = environ.get(
|
||||||
"SPIFFWORKFLOW_BACKEND_URL", default="http://localhost:7000"
|
"SPIFFWORKFLOW_BACKEND_URL", default="http://localhost:7000"
|
||||||
)
|
)
|
||||||
|
# service task connector proxy
|
||||||
|
CONNECTOR_PROXY_URL = environ.get(
|
||||||
|
"CONNECTOR_PROXY_URL", default="http://localhost:7004"
|
||||||
|
)
|
||||||
|
|
||||||
GIT_COMMIT_ON_SAVE = environ.get("GIT_COMMIT_ON_SAVE", default="false") == "true"
|
GIT_COMMIT_ON_SAVE = environ.get("GIT_COMMIT_ON_SAVE", default="false") == "true"
|
||||||
|
|
||||||
|
@ -37,11 +41,6 @@ SPIFFWORKFLOW_BACKEND_LOG_TO_FILE = (
|
||||||
environ.get("SPIFFWORKFLOW_BACKEND_LOG_TO_FILE", default="false") == "true"
|
environ.get("SPIFFWORKFLOW_BACKEND_LOG_TO_FILE", default="false") == "true"
|
||||||
)
|
)
|
||||||
|
|
||||||
# service task connector proxy
|
|
||||||
CONNECTOR_PROXY_URL = environ.get(
|
|
||||||
"CONNECTOR_PROXY_URL", default="http://localhost:7004"
|
|
||||||
)
|
|
||||||
|
|
||||||
SPIFFWORKFLOW_BACKEND_PERMISSIONS_FILE_NAME = environ.get(
|
SPIFFWORKFLOW_BACKEND_PERMISSIONS_FILE_NAME = environ.get(
|
||||||
"SPIFFWORKFLOW_BACKEND_PERMISSIONS_FILE_NAME"
|
"SPIFFWORKFLOW_BACKEND_PERMISSIONS_FILE_NAME"
|
||||||
)
|
)
|
||||||
|
|
|
@ -31,12 +31,8 @@ class ProcessModelInfo:
|
||||||
description: str
|
description: str
|
||||||
process_group_id: str = ""
|
process_group_id: str = ""
|
||||||
process_group: Any | None = None
|
process_group: Any | None = None
|
||||||
is_master_spec: bool | None = False
|
|
||||||
standalone: bool | None = False
|
|
||||||
library: bool | None = False
|
|
||||||
primary_file_name: str | None = None
|
primary_file_name: str | None = None
|
||||||
primary_process_id: str | None = None
|
primary_process_id: str | None = None
|
||||||
libraries: list[str] = field(default_factory=list)
|
|
||||||
display_order: int | None = 0
|
display_order: int | None = 0
|
||||||
is_review: bool = False
|
is_review: bool = False
|
||||||
files: list[File] | None = field(default_factory=list[File])
|
files: list[File] | None = field(default_factory=list[File])
|
||||||
|
@ -67,15 +63,11 @@ class ProcessModelInfoSchema(Schema):
|
||||||
id = marshmallow.fields.String(required=True)
|
id = marshmallow.fields.String(required=True)
|
||||||
display_name = marshmallow.fields.String(required=True)
|
display_name = marshmallow.fields.String(required=True)
|
||||||
description = marshmallow.fields.String()
|
description = marshmallow.fields.String()
|
||||||
is_master_spec = marshmallow.fields.Boolean(required=True)
|
|
||||||
standalone = marshmallow.fields.Boolean(required=True)
|
|
||||||
library = marshmallow.fields.Boolean(required=True)
|
|
||||||
display_order = marshmallow.fields.Integer(allow_none=True)
|
display_order = marshmallow.fields.Integer(allow_none=True)
|
||||||
primary_file_name = marshmallow.fields.String(allow_none=True)
|
primary_file_name = marshmallow.fields.String(allow_none=True)
|
||||||
primary_process_id = marshmallow.fields.String(allow_none=True)
|
primary_process_id = marshmallow.fields.String(allow_none=True)
|
||||||
is_review = marshmallow.fields.Boolean(allow_none=True)
|
is_review = marshmallow.fields.Boolean(allow_none=True)
|
||||||
process_group_id = marshmallow.fields.String(allow_none=True)
|
process_group_id = marshmallow.fields.String(allow_none=True)
|
||||||
libraries = marshmallow.fields.List(marshmallow.fields.String(), allow_none=True)
|
|
||||||
files = marshmallow.fields.List(marshmallow.fields.Nested("FileSchema"))
|
files = marshmallow.fields.List(marshmallow.fields.Nested("FileSchema"))
|
||||||
fault_or_suspend_on_exception = marshmallow.fields.String()
|
fault_or_suspend_on_exception = marshmallow.fields.String()
|
||||||
exception_notification_addresses = marshmallow.fields.List(
|
exception_notification_addresses = marshmallow.fields.List(
|
||||||
|
|
|
@ -774,6 +774,17 @@ def service_tasks_show() -> flask.wrappers.Response:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def authentication_list() -> flask.wrappers.Response:
|
||||||
|
"""Authentication_list."""
|
||||||
|
available_authentications = ServiceTaskService.authentication_list()
|
||||||
|
response_json = {
|
||||||
|
"results": available_authentications,
|
||||||
|
"connector_proxy_base_url": current_app.config["CONNECTOR_PROXY_URL"],
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response(json.dumps(response_json), status=200, mimetype="application/json")
|
||||||
|
|
||||||
|
|
||||||
def process_instance_report_show(
|
def process_instance_report_show(
|
||||||
process_group_id: str,
|
process_group_id: str,
|
||||||
process_model_id: str,
|
process_model_id: str,
|
||||||
|
|
|
@ -20,11 +20,6 @@ class FileSystemService:
|
||||||
""" Simple Service meant for extension that provides some useful
|
""" Simple Service meant for extension that provides some useful
|
||||||
methods for dealing with the File system.
|
methods for dealing with the File system.
|
||||||
"""
|
"""
|
||||||
LIBRARY_SPECS = "Library Specs"
|
|
||||||
STAND_ALONE_SPECS = "Stand Alone"
|
|
||||||
MASTER_SPECIFICATION = "Master Specification"
|
|
||||||
REFERENCE_FILES = "Reference Files"
|
|
||||||
SPECIAL_FOLDERS = [LIBRARY_SPECS, MASTER_SPECIFICATION, REFERENCE_FILES]
|
|
||||||
CAT_JSON_FILE = "process_group.json"
|
CAT_JSON_FILE = "process_group.json"
|
||||||
WF_JSON_FILE = "workflow.json"
|
WF_JSON_FILE = "workflow.json"
|
||||||
|
|
||||||
|
@ -41,13 +36,6 @@ class FileSystemService:
|
||||||
"""Category_path."""
|
"""Category_path."""
|
||||||
return os.path.join(FileSystemService.root_path(), name)
|
return os.path.join(FileSystemService.root_path(), name)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def library_path(name: str) -> str:
|
|
||||||
"""Library_path."""
|
|
||||||
return os.path.join(
|
|
||||||
FileSystemService.root_path(), FileSystemService.LIBRARY_SPECS, name
|
|
||||||
)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def full_path_from_relative_path(relative_path: str) -> str:
|
def full_path_from_relative_path(relative_path: str) -> str:
|
||||||
"""Full_path_from_relative_path."""
|
"""Full_path_from_relative_path."""
|
||||||
|
@ -66,32 +54,13 @@ class FileSystemService:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def process_group_path_for_spec(spec: ProcessModelInfo) -> str:
|
def process_group_path_for_spec(spec: ProcessModelInfo) -> str:
|
||||||
"""Category_path_for_spec."""
|
"""Category_path_for_spec."""
|
||||||
if spec.is_master_spec:
|
return FileSystemService.process_group_path(spec.process_group_id)
|
||||||
return os.path.join(FileSystemService.root_path())
|
|
||||||
elif spec.library:
|
|
||||||
process_group_path = FileSystemService.process_group_path(
|
|
||||||
FileSystemService.LIBRARY_SPECS
|
|
||||||
)
|
|
||||||
elif spec.standalone:
|
|
||||||
process_group_path = FileSystemService.process_group_path(
|
|
||||||
FileSystemService.STAND_ALONE_SPECS
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
process_group_path = FileSystemService.process_group_path(
|
|
||||||
spec.process_group_id
|
|
||||||
)
|
|
||||||
return process_group_path
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def workflow_path(spec: ProcessModelInfo) -> str:
|
def workflow_path(spec: ProcessModelInfo) -> str:
|
||||||
"""Workflow_path."""
|
"""Workflow_path."""
|
||||||
if spec.is_master_spec:
|
process_group_path = FileSystemService.process_group_path_for_spec(spec)
|
||||||
return os.path.join(
|
return os.path.join(process_group_path, spec.id)
|
||||||
FileSystemService.root_path(), FileSystemService.MASTER_SPECIFICATION
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
process_group_path = FileSystemService.process_group_path_for_spec(spec)
|
|
||||||
return os.path.join(process_group_path, spec.id)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def full_path_to_process_model_file(spec: ProcessModelInfo, file_name: str) -> str:
|
def full_path_to_process_model_file(spec: ProcessModelInfo, file_name: str) -> str:
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
"""Process_instance_processor."""
|
"""Process_instance_processor."""
|
||||||
|
import _strptime # type: ignore
|
||||||
import decimal
|
import decimal
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
@ -95,6 +96,7 @@ DEFAULT_GLOBALS.update(
|
||||||
"datetime": datetime,
|
"datetime": datetime,
|
||||||
"time": time,
|
"time": time,
|
||||||
"decimal": decimal,
|
"decimal": decimal,
|
||||||
|
"_strptime": _strptime,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
# This will overwrite the standard builtins
|
# This will overwrite the standard builtins
|
||||||
|
@ -343,9 +345,7 @@ class ProcessInstanceProcessor:
|
||||||
f"The given process model was not found: {process_group_identifier}/{process_model_identifier}.",
|
f"The given process model was not found: {process_group_identifier}/{process_model_identifier}.",
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
spec_files = SpecFileService.get_files(
|
spec_files = SpecFileService.get_files(process_model_info)
|
||||||
process_model_info, include_libraries=True
|
|
||||||
)
|
|
||||||
return cls.get_spec(spec_files, process_model_info)
|
return cls.get_spec(spec_files, process_model_info)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
@ -217,9 +217,6 @@ class ProcessInstanceService:
|
||||||
message="A process instance must have a user_id.",
|
message="A process instance must have a user_id.",
|
||||||
task=spiff_task,
|
task=spiff_task,
|
||||||
)
|
)
|
||||||
# # Standalone workflow - we only care about the current user
|
|
||||||
# elif processor.workflow_model.study_id is None and processor.workflow_model.user_id is not None:
|
|
||||||
# return [processor.workflow_model.user_id]
|
|
||||||
|
|
||||||
# Workflow associated with a study - get all the users
|
# Workflow associated with a study - get all the users
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -63,12 +63,6 @@ class ProcessModelService(FileSystemService):
|
||||||
def save_process_model(self, process_model: ProcessModelInfo) -> None:
|
def save_process_model(self, process_model: ProcessModelInfo) -> None:
|
||||||
"""Save_process_model."""
|
"""Save_process_model."""
|
||||||
spec_path = self.workflow_path(process_model)
|
spec_path = self.workflow_path(process_model)
|
||||||
if (
|
|
||||||
process_model.is_master_spec
|
|
||||||
or process_model.library
|
|
||||||
or process_model.standalone
|
|
||||||
):
|
|
||||||
process_model.process_group_id = ""
|
|
||||||
os.makedirs(spec_path, exist_ok=True)
|
os.makedirs(spec_path, exist_ok=True)
|
||||||
json_path = os.path.join(spec_path, self.WF_JSON_FILE)
|
json_path = os.path.join(spec_path, self.WF_JSON_FILE)
|
||||||
with open(json_path, "w") as wf_json:
|
with open(json_path, "w") as wf_json:
|
||||||
|
@ -90,20 +84,6 @@ class ProcessModelService(FileSystemService):
|
||||||
path = self.workflow_path(process_model)
|
path = self.workflow_path(process_model)
|
||||||
shutil.rmtree(path)
|
shutil.rmtree(path)
|
||||||
|
|
||||||
@property
|
|
||||||
def master_spec(self) -> Optional[ProcessModelInfo]:
|
|
||||||
"""Master_spec."""
|
|
||||||
return self.get_master_spec()
|
|
||||||
|
|
||||||
def get_master_spec(self) -> Optional[ProcessModelInfo]:
|
|
||||||
"""Get_master_spec."""
|
|
||||||
path = os.path.join(
|
|
||||||
FileSystemService.root_path(), FileSystemService.MASTER_SPECIFICATION
|
|
||||||
)
|
|
||||||
if os.path.exists(path):
|
|
||||||
return self.__scan_spec(path, FileSystemService.MASTER_SPECIFICATION)
|
|
||||||
return None
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_process_model_from_relative_path(
|
def get_process_model_from_relative_path(
|
||||||
cls, relative_path: str
|
cls, relative_path: str
|
||||||
|
@ -121,9 +101,6 @@ class ProcessModelService(FileSystemService):
|
||||||
if not os.path.exists(FileSystemService.root_path()):
|
if not os.path.exists(FileSystemService.root_path()):
|
||||||
raise ProcessEntityNotFoundError("process_model_not_found")
|
raise ProcessEntityNotFoundError("process_model_not_found")
|
||||||
|
|
||||||
master_spec = self.get_master_spec()
|
|
||||||
if master_spec and master_spec.id == process_model_id:
|
|
||||||
return master_spec
|
|
||||||
if group_id is not None:
|
if group_id is not None:
|
||||||
process_group = self.get_process_group(group_id)
|
process_group = self.get_process_group(group_id)
|
||||||
if process_group is not None:
|
if process_group is not None:
|
||||||
|
@ -168,20 +145,6 @@ class ProcessModelService(FileSystemService):
|
||||||
process_groups.sort()
|
process_groups.sort()
|
||||||
return process_groups
|
return process_groups
|
||||||
|
|
||||||
def get_libraries(self) -> List[ProcessModelInfo]:
|
|
||||||
"""Get_libraries."""
|
|
||||||
process_group = self.get_process_group(self.LIBRARY_SPECS)
|
|
||||||
if not process_group:
|
|
||||||
return []
|
|
||||||
return process_group.process_models
|
|
||||||
|
|
||||||
def get_standalones(self) -> List[ProcessModelInfo]:
|
|
||||||
"""Get_standalones."""
|
|
||||||
process_group = self.get_process_group(self.STAND_ALONE_SPECS)
|
|
||||||
if not process_group:
|
|
||||||
return []
|
|
||||||
return process_group.process_models
|
|
||||||
|
|
||||||
def get_process_group(self, process_group_id: str) -> ProcessGroup:
|
def get_process_group(self, process_group_id: str) -> ProcessGroup:
|
||||||
"""Look for a given process_group, and return it."""
|
"""Look for a given process_group, and return it."""
|
||||||
if os.path.exists(FileSystemService.root_path()):
|
if os.path.exists(FileSystemService.root_path()):
|
||||||
|
@ -240,14 +203,6 @@ class ProcessModelService(FileSystemService):
|
||||||
process_groups = []
|
process_groups = []
|
||||||
for item in directory_items:
|
for item in directory_items:
|
||||||
if item.is_dir() and not item.name[0] == ".":
|
if item.is_dir() and not item.name[0] == ".":
|
||||||
# if item.name == self.REFERENCE_FILES:
|
|
||||||
# continue
|
|
||||||
# elif item.name == self.MASTER_SPECIFICATION:
|
|
||||||
# continue
|
|
||||||
# elif item.name == self.LIBRARY_SPECS:
|
|
||||||
# continue
|
|
||||||
# elif item.name == self.STAND_ALONE_SPECS:
|
|
||||||
# continue
|
|
||||||
process_groups.append(self.__scan_process_group(item))
|
process_groups.append(self.__scan_process_group(item))
|
||||||
return process_groups
|
return process_groups
|
||||||
|
|
||||||
|
@ -292,7 +247,6 @@ class ProcessModelService(FileSystemService):
|
||||||
) -> ProcessModelInfo:
|
) -> ProcessModelInfo:
|
||||||
"""__scan_spec."""
|
"""__scan_spec."""
|
||||||
spec_path = os.path.join(path, self.WF_JSON_FILE)
|
spec_path = os.path.join(path, self.WF_JSON_FILE)
|
||||||
is_master = FileSystemService.MASTER_SPECIFICATION in spec_path
|
|
||||||
|
|
||||||
if os.path.exists(spec_path):
|
if os.path.exists(spec_path):
|
||||||
with open(spec_path) as wf_json:
|
with open(spec_path) as wf_json:
|
||||||
|
@ -312,14 +266,10 @@ class ProcessModelService(FileSystemService):
|
||||||
|
|
||||||
spec = ProcessModelInfo(
|
spec = ProcessModelInfo(
|
||||||
id=name,
|
id=name,
|
||||||
library=False,
|
|
||||||
standalone=False,
|
|
||||||
is_master_spec=is_master,
|
|
||||||
display_name=name,
|
display_name=name,
|
||||||
description="",
|
description="",
|
||||||
display_order=0,
|
display_order=0,
|
||||||
is_review=False,
|
is_review=False,
|
||||||
libraries=[],
|
|
||||||
)
|
)
|
||||||
with open(spec_path, "w") as wf_json:
|
with open(spec_path, "w") as wf_json:
|
||||||
json.dump(self.WF_SCHEMA.dump(spec), wf_json, indent=4)
|
json.dump(self.WF_SCHEMA.dump(spec), wf_json, indent=4)
|
||||||
|
|
|
@ -9,6 +9,10 @@ from spiffworkflow_backend.services.file_system_service import FileSystemService
|
||||||
from spiffworkflow_backend.services.secret_service import SecretService
|
from spiffworkflow_backend.services.secret_service import SecretService
|
||||||
|
|
||||||
|
|
||||||
|
class ConnectorProxyError(Exception):
|
||||||
|
"""ConnectorProxyError."""
|
||||||
|
|
||||||
|
|
||||||
def connector_proxy_url() -> Any:
|
def connector_proxy_url() -> Any:
|
||||||
"""Returns the connector proxy url."""
|
"""Returns the connector proxy url."""
|
||||||
return current_app.config["CONNECTOR_PROXY_URL"]
|
return current_app.config["CONNECTOR_PROXY_URL"]
|
||||||
|
@ -73,3 +77,18 @@ class ServiceTaskService:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e)
|
print(e)
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def authentication_list() -> Any:
|
||||||
|
"""Returns a list of available authentications."""
|
||||||
|
try:
|
||||||
|
response = requests.get(f"{connector_proxy_url()}/v1/auths")
|
||||||
|
|
||||||
|
if response.status_code != 200:
|
||||||
|
return []
|
||||||
|
|
||||||
|
parsed_response = json.loads(response.text)
|
||||||
|
return parsed_response
|
||||||
|
except Exception as exception:
|
||||||
|
current_app.logger.error(exception)
|
||||||
|
raise ConnectorProxyError(exception.__class__.__name__) from exception
|
||||||
|
|
|
@ -39,22 +39,15 @@ class SpecFileService(FileSystemService):
|
||||||
def get_files(
|
def get_files(
|
||||||
process_model_info: ProcessModelInfo,
|
process_model_info: ProcessModelInfo,
|
||||||
file_name: Optional[str] = None,
|
file_name: Optional[str] = None,
|
||||||
include_libraries: bool = False,
|
|
||||||
extension_filter: str = "",
|
extension_filter: str = "",
|
||||||
) -> List[File]:
|
) -> List[File]:
|
||||||
"""Return all files associated with a workflow specification."""
|
"""Return all files associated with a workflow specification."""
|
||||||
path = SpecFileService.workflow_path(process_model_info)
|
path = SpecFileService.workflow_path(process_model_info)
|
||||||
files = SpecFileService._get_files(path, file_name)
|
files = SpecFileService._get_files(path, file_name)
|
||||||
if include_libraries:
|
|
||||||
for lib_name in process_model_info.libraries:
|
|
||||||
lib_path = SpecFileService.library_path(lib_name)
|
|
||||||
files.extend(SpecFileService._get_files(lib_path, file_name))
|
|
||||||
|
|
||||||
if extension_filter != "":
|
if extension_filter != "":
|
||||||
files = list(
|
files = list(
|
||||||
filter(lambda file: file.name.endswith(extension_filter), files)
|
filter(lambda file: file.name.endswith(extension_filter), files)
|
||||||
)
|
)
|
||||||
|
|
||||||
return files
|
return files
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -96,13 +89,6 @@ class SpecFileService(FileSystemService):
|
||||||
def get_data(process_model_info: ProcessModelInfo, file_name: str) -> bytes:
|
def get_data(process_model_info: ProcessModelInfo, file_name: str) -> bytes:
|
||||||
"""Get_data."""
|
"""Get_data."""
|
||||||
file_path = SpecFileService.file_path(process_model_info, file_name)
|
file_path = SpecFileService.file_path(process_model_info, file_name)
|
||||||
if not os.path.exists(file_path):
|
|
||||||
# If the file isn't here, it may be in a library
|
|
||||||
for lib in process_model_info.libraries:
|
|
||||||
file_path = SpecFileService.library_path(lib)
|
|
||||||
file_path = os.path.join(file_path, file_name)
|
|
||||||
if os.path.exists(file_path):
|
|
||||||
break
|
|
||||||
if not os.path.exists(file_path):
|
if not os.path.exists(file_path):
|
||||||
raise ApiError(
|
raise ApiError(
|
||||||
"unknown_file",
|
"unknown_file",
|
||||||
|
|
|
@ -115,11 +115,7 @@ class BaseTest:
|
||||||
display_name=process_model_display_name,
|
display_name=process_model_display_name,
|
||||||
description=process_model_description,
|
description=process_model_description,
|
||||||
process_group_id=process_group.id,
|
process_group_id=process_group.id,
|
||||||
standalone=False,
|
|
||||||
is_review=False,
|
is_review=False,
|
||||||
is_master_spec=False,
|
|
||||||
libraries=[],
|
|
||||||
library=False,
|
|
||||||
primary_process_id=primary_process_id,
|
primary_process_id=primary_process_id,
|
||||||
primary_file_name=primary_file_name,
|
primary_file_name=primary_file_name,
|
||||||
fault_or_suspend_on_exception=fault_or_suspend_on_exception,
|
fault_or_suspend_on_exception=fault_or_suspend_on_exception,
|
||||||
|
|
|
@ -18,12 +18,9 @@ class ExampleDataLoader:
|
||||||
process_model_id: str,
|
process_model_id: str,
|
||||||
display_name: str = "",
|
display_name: str = "",
|
||||||
description: str = "",
|
description: str = "",
|
||||||
master_spec: bool = False,
|
|
||||||
process_group_id: str = "",
|
process_group_id: str = "",
|
||||||
display_order: int = 0,
|
display_order: int = 0,
|
||||||
from_tests: bool = False,
|
from_tests: bool = False,
|
||||||
standalone: bool = False,
|
|
||||||
library: bool = False,
|
|
||||||
bpmn_file_name: Optional[str] = None,
|
bpmn_file_name: Optional[str] = None,
|
||||||
process_model_source_directory: Optional[str] = None,
|
process_model_source_directory: Optional[str] = None,
|
||||||
) -> ProcessModelInfo:
|
) -> ProcessModelInfo:
|
||||||
|
@ -38,11 +35,7 @@ class ExampleDataLoader:
|
||||||
description=description,
|
description=description,
|
||||||
process_group_id=process_group_id,
|
process_group_id=process_group_id,
|
||||||
display_order=display_order,
|
display_order=display_order,
|
||||||
is_master_spec=master_spec,
|
|
||||||
standalone=standalone,
|
|
||||||
library=library,
|
|
||||||
is_review=False,
|
is_review=False,
|
||||||
libraries=[],
|
|
||||||
)
|
)
|
||||||
workflow_spec_service = ProcessModelService()
|
workflow_spec_service = ProcessModelService()
|
||||||
workflow_spec_service.add_spec(spec)
|
workflow_spec_service.add_spec(spec)
|
||||||
|
|
|
@ -37,9 +37,7 @@ def assure_process_group_exists(process_group_id: Optional[str] = None) -> Proce
|
||||||
|
|
||||||
def load_test_spec(
|
def load_test_spec(
|
||||||
process_model_id: str,
|
process_model_id: str,
|
||||||
master_spec: bool = False,
|
|
||||||
process_group_id: Optional[str] = None,
|
process_group_id: Optional[str] = None,
|
||||||
library: bool = False,
|
|
||||||
bpmn_file_name: Optional[str] = None,
|
bpmn_file_name: Optional[str] = None,
|
||||||
process_model_source_directory: Optional[str] = None,
|
process_model_source_directory: Optional[str] = None,
|
||||||
) -> ProcessModelInfo:
|
) -> ProcessModelInfo:
|
||||||
|
@ -48,9 +46,8 @@ def load_test_spec(
|
||||||
process_model_service = ProcessModelService()
|
process_model_service = ProcessModelService()
|
||||||
if process_group_id is None:
|
if process_group_id is None:
|
||||||
process_group_id = "test_process_group_id"
|
process_group_id = "test_process_group_id"
|
||||||
if not master_spec and not library:
|
process_group = assure_process_group_exists(process_group_id)
|
||||||
process_group = assure_process_group_exists(process_group_id)
|
process_group_id = process_group.id
|
||||||
process_group_id = process_group.id
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
return process_model_service.get_process_model(
|
return process_model_service.get_process_model(
|
||||||
|
@ -59,11 +56,9 @@ def load_test_spec(
|
||||||
except ProcessEntityNotFoundError:
|
except ProcessEntityNotFoundError:
|
||||||
spec = ExampleDataLoader().create_spec(
|
spec = ExampleDataLoader().create_spec(
|
||||||
process_model_id=process_model_id,
|
process_model_id=process_model_id,
|
||||||
master_spec=master_spec,
|
|
||||||
from_tests=True,
|
from_tests=True,
|
||||||
display_name=process_model_id,
|
display_name=process_model_id,
|
||||||
process_group_id=process_group_id,
|
process_group_id=process_group_id,
|
||||||
library=library,
|
|
||||||
bpmn_file_name=bpmn_file_name,
|
bpmn_file_name=bpmn_file_name,
|
||||||
process_model_source_directory=process_model_source_directory,
|
process_model_source_directory=process_model_source_directory,
|
||||||
)
|
)
|
||||||
|
|
|
@ -20,7 +20,6 @@ class TestProcessModel(BaseTest):
|
||||||
id="model_one", display_name="Model One"
|
id="model_one", display_name="Model One"
|
||||||
)
|
)
|
||||||
assert process_model_one.files == []
|
assert process_model_one.files == []
|
||||||
assert process_model_one.libraries == []
|
|
||||||
|
|
||||||
def test_can_run_process_model_with_call_activities_when_in_same_process_model_directory(
|
def test_can_run_process_model_with_call_activities_when_in_same_process_model_directory(
|
||||||
self, app: Flask, with_db_and_bpmn_file_cleanup: None
|
self, app: Flask, with_db_and_bpmn_file_cleanup: None
|
||||||
|
|
Loading…
Reference in New Issue