diff --git a/Pipfile.lock b/Pipfile.lock index ff3840b4..bd8581a5 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -533,34 +533,34 @@ }, "numpy": { "hashes": [ - "sha256:13af0184177469192d80db9bd02619f6fa8b922f9f327e077d6f2a6acb1ce1c0", - "sha256:26a45798ca2a4e168d00de75d4a524abf5907949231512f372b217ede3429e98", - "sha256:26f509450db547e4dfa3ec739419b31edad646d21fb8d0ed0734188b35ff6b27", - "sha256:30a59fb41bb6b8c465ab50d60a1b298d1cd7b85274e71f38af5a75d6c475d2d2", - "sha256:33c623ef9ca5e19e05991f127c1be5aeb1ab5cdf30cb1c5cf3960752e58b599b", - "sha256:356f96c9fbec59974a592452ab6a036cd6f180822a60b529a975c9467fcd5f23", - "sha256:3c40c827d36c6d1c3cf413694d7dc843d50997ebffbc7c87d888a203ed6403a7", - "sha256:4d054f013a1983551254e2379385e359884e5af105e3efe00418977d02f634a7", - "sha256:63d971bb211ad3ca37b2adecdd5365f40f3b741a455beecba70fd0dde8b2a4cb", - "sha256:658624a11f6e1c252b2cd170d94bf28c8f9410acab9f2fd4369e11e1cd4e1aaf", - "sha256:76766cc80d6128750075378d3bb7812cf146415bd29b588616f72c943c00d598", - "sha256:7b57f26e5e6ee2f14f960db46bd58ffdca25ca06dd997729b1b179fddd35f5a3", - "sha256:7b852817800eb02e109ae4a9cef2beda8dd50d98b76b6cfb7b5c0099d27b52d4", - "sha256:8cde829f14bd38f6da7b2954be0f2837043e8b8d7a9110ec5e318ae6bf706610", - "sha256:a2e3a39f43f0ce95204beb8fe0831199542ccab1e0c6e486a0b4947256215632", - "sha256:a86c962e211f37edd61d6e11bb4df7eddc4a519a38a856e20a6498c319efa6b0", - "sha256:a8705c5073fe3fcc297fb8e0b31aa794e05af6a329e81b7ca4ffecab7f2b95ef", - "sha256:b6aaeadf1e4866ca0fdf7bb4eed25e521ae21a7947c59f78154b24fc7abbe1dd", - "sha256:be62aeff8f2f054eff7725f502f6228298891fd648dc2630e03e44bf63e8cee0", - "sha256:c2edbb783c841e36ca0fa159f0ae97a88ce8137fb3a6cd82eae77349ba4b607b", - "sha256:cbe326f6d364375a8e5a8ccb7e9cd73f4b2f6dc3b2ed205633a0db8243e2a96a", - "sha256:d34fbb98ad0d6b563b95de852a284074514331e6b9da0a9fc894fb1cdae7a79e", - "sha256:d97a86937cf9970453c3b62abb55a6475f173347b4cde7f8dcdb48c8e1b9952d", - "sha256:dd53d7c4a69e766e4900f29db5872f5824a06827d594427cf1a4aa542818b796", - "sha256:df1889701e2dfd8ba4dc9b1a010f0a60950077fb5242bb92c8b5c7f1a6f2668a", - "sha256:fa1fe75b4a9e18b66ae7f0b122543c42debcf800aaafa0212aaff3ad273c2596" + "sha256:082f8d4dd69b6b688f64f509b91d482362124986d98dc7dc5f5e9f9b9c3bb983", + "sha256:1bc0145999e8cb8aed9d4e65dd8b139adf1919e521177f198529687dbf613065", + "sha256:309cbcfaa103fc9a33ec16d2d62569d541b79f828c382556ff072442226d1968", + "sha256:3673c8b2b29077f1b7b3a848794f8e11f401ba0b71c49fbd26fb40b71788b132", + "sha256:480fdd4dbda4dd6b638d3863da3be82873bba6d32d1fc12ea1b8486ac7b8d129", + "sha256:56ef7f56470c24bb67fb43dae442e946a6ce172f97c69f8d067ff8550cf782ff", + "sha256:5a936fd51049541d86ccdeef2833cc89a18e4d3808fe58a8abeb802665c5af93", + "sha256:5b6885c12784a27e957294b60f97e8b5b4174c7504665333c5e94fbf41ae5d6a", + "sha256:667c07063940e934287993366ad5f56766bc009017b4a0fe91dbd07960d0aba7", + "sha256:7ed448ff4eaffeb01094959b19cbaf998ecdee9ef9932381420d514e446601cd", + "sha256:8343bf67c72e09cfabfab55ad4a43ce3f6bf6e6ced7acf70f45ded9ebb425055", + "sha256:92feb989b47f83ebef246adabc7ff3b9a59ac30601c3f6819f8913458610bdcc", + "sha256:935c27ae2760c21cd7354402546f6be21d3d0c806fffe967f745d5f2de5005a7", + "sha256:aaf42a04b472d12515debc621c31cf16c215e332242e7a9f56403d814c744624", + "sha256:b12e639378c741add21fbffd16ba5ad25c0a1a17cf2b6fe4288feeb65144f35b", + "sha256:b1cca51512299841bf69add3b75361779962f9cee7d9ee3bb446d5982e925b69", + "sha256:b8456987b637232602ceb4d663cb34106f7eb780e247d51a260b84760fd8f491", + "sha256:b9792b0ac0130b277536ab8944e7b754c69560dac0415dd4b2dbd16b902c8954", + "sha256:c9591886fc9cbe5532d5df85cb8e0cc3b44ba8ce4367bd4cf1b93dc19713da72", + "sha256:cf1347450c0b7644ea142712619533553f02ef23f92f781312f6a3553d031fc7", + "sha256:de8b4a9b56255797cbddb93281ed92acbc510fb7b15df3f01bd28f46ebc4edae", + "sha256:e1b1dc0372f530f26a03578ac75d5e51b3868b9b76cd2facba4c9ee0eb252ab1", + "sha256:e45f8e981a0ab47103181773cc0a54e650b2aef8c7b6cd07405d0fa8d869444a", + "sha256:e4f6d3c53911a9d103d8ec9518190e52a8b945bab021745af4939cfc7c0d4a9e", + "sha256:ed8a311493cf5480a2ebc597d1e177231984c818a86875126cfd004241a73c3e", + "sha256:ef71a1d4fd4858596ae80ad1ec76404ad29701f8ca7cdcebc50300178db14dfc" ], - "version": "==1.19.0" + "version": "==1.19.1" }, "openapi-spec-validator": { "hashes": [ @@ -685,6 +685,13 @@ ], "version": "==0.16.0" }, + "python-box": { + "hashes": [ + "sha256:2df0d0e0769b6d6e7daed8d5e0b10a38e0b5486ee75914c30f2a927f7a374111", + "sha256:ddea019b4ee53fe3f822407b0b26ec54ff6233042c68b54244d3503ae4d6218f" + ], + "version": "==5.0.1" + }, "python-dateutil": { "hashes": [ "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c", @@ -886,7 +893,7 @@ "spiffworkflow": { "editable": true, "git": "https://github.com/sartography/SpiffWorkflow.git", - "ref": "161b3e2ac62a824c6b771e9b817a2bd477af0d17" + "ref": "74529738b4e16be5aadd846669a201560f81a6d4" }, "sqlalchemy": { "hashes": [ diff --git a/crc/api.yml b/crc/api.yml index 3d504ad4..4c6ebd1b 100644 --- a/crc/api.yml +++ b/crc/api.yml @@ -838,6 +838,33 @@ paths: type: array items: $ref: "#/components/schemas/Script" + /eval: + parameters: + - name: expression + in: query + required: true + description: The python expression to execute. + schema: + type: string + put: + operationId: crc.api.tools.evaluate_python_expression + summary: Execute the given python expression, with the given json data structure used as local variables, returns the result of the evaluation. + tags: + - Configurator Tools + requestBody: + description: The json data to use as local variables when evaluating the expresson. + required: true + content: + application/json: + schema: + type: object + responses: + '200': + description: Returns the result of executing the given python script. + content: + text/plain: + schema: + type: string /approval-counts: parameters: - name: as_user diff --git a/crc/api/tools.py b/crc/api/tools.py index 760d0d71..de30d10d 100644 --- a/crc/api/tools.py +++ b/crc/api/tools.py @@ -2,6 +2,7 @@ import io import json import connexion +from SpiffWorkflow.bpmn.PythonScriptEngine import PythonScriptEngine from flask import send_file from jinja2 import Template, UndefinedError @@ -10,6 +11,7 @@ from crc.scripts.complete_template import CompleteTemplate from crc.scripts.script import Script import crc.scripts from crc.services.mails import send_test_email +from crc.services.workflow_processor import WorkflowProcessor def render_markdown(data, template): @@ -61,8 +63,22 @@ def list_scripts(): }) return script_meta + def send_email(address): """Just sends a quick test email to assure the system is working.""" if not address: address = "dan@sartography.com" return send_test_email(address, [address]) + + +def evaluate_python_expression(expression, body): + """Evaluate the given python expression, returning it's result. This is useful if the + front end application needs to do real-time processing on task data. If for instance + there is a hide expression that is based on a previous value in the same form.""" + try: + # fixme: The script engine should be pulled from Workflow Processor, + # but the one it returns overwrites the evaluate expression making it uncallable. + script_engine = PythonScriptEngine() + return script_engine.evaluate(expression, **body) + except Exception as e: + raise ApiError("expression_error", str(e)) diff --git a/tests/test_tools_api.py b/tests/test_tools_api.py index c6f543c1..3ddf9fea 100644 --- a/tests/test_tools_api.py +++ b/tests/test_tools_api.py @@ -37,3 +37,12 @@ class TestStudyApi(BaseTest): self.assertTrue(len(scripts) > 1) self.assertIsNotNone(scripts[0]['name']) self.assertIsNotNone(scripts[0]['description']) + + def test_eval_hide_expression(self): + """Assures we can use python to process a hide expression fron the front end""" + rv = self.app.put('/v1.0/eval?expression=x.y==2', + data='{"x":{"y":2}}', follow_redirects=True, + content_type='application/json', + headers=self.logged_in_headers()) + self.assert_success(rv) + self.assertEqual("true", rv.get_data(as_text=True).strip())