Merge pull request #327 from sartography/feature/file_refactor_2
modified the tools api to return the expression and data with the res…
This commit is contained in:
commit
508c265952
|
@ -957,7 +957,7 @@
|
|||
},
|
||||
"spiffworkflow": {
|
||||
"git": "https://github.com/sartography/SpiffWorkflow.git",
|
||||
"ref": "ce939de158246e9d10e7e154c92230669354bc64"
|
||||
"ref": "da79e8b0f66df1cb8372435bdff3b294e5f3a336"
|
||||
},
|
||||
"sqlalchemy": {
|
||||
"hashes": [
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import hashlib
|
||||
import io
|
||||
import json
|
||||
|
||||
|
@ -78,11 +79,13 @@ def send_email(subject, address, body, data=None):
|
|||
def evaluate_python_expression(body):
|
||||
"""Evaluate the given python expression, returning its 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."""
|
||||
there is a hide expression that is based on a previous value in the same form.
|
||||
The response includes both the result, and a hash of the original query, subsequent calls
|
||||
of the same hash are unnecessary. """
|
||||
try:
|
||||
script_engine = CustomBpmnScriptEngine()
|
||||
result = script_engine.eval(body['expression'], body['data'])
|
||||
return {"result": result}
|
||||
return {"result": result, "expression": body['expression'], "data": body['data']}
|
||||
except Exception as e:
|
||||
raise ApiError("expression_error", f"Failed to evaluate the expression '%s'. %s" %
|
||||
(body['expression'], str(e)),
|
||||
|
|
|
@ -259,19 +259,34 @@ class WorkflowService(object):
|
|||
"""Looks through the fields in a submitted form, acting on any properties."""
|
||||
if not hasattr(task.task_spec, 'form'): return
|
||||
for field in task.task_spec.form.fields:
|
||||
if field.has_property(Task.FIELD_PROP_DOC_CODE) and \
|
||||
field.type == Task.FIELD_TYPE_FILE:
|
||||
file_id = task.data[field.id]
|
||||
file = db.session.query(FileModel).filter(FileModel.id == file_id).first()
|
||||
doc_code = WorkflowService.evaluate_property(Task.FIELD_PROP_DOC_CODE, field, task)
|
||||
data = task.data
|
||||
if field.has_property(Task.FIELD_PROP_REPEAT):
|
||||
repeat_array = task.data[field.get_property(Task.FIELD_PROP_REPEAT)]
|
||||
for repeat_data in repeat_array:
|
||||
WorkflowService.__post_process_field(task, field, repeat_data)
|
||||
else:
|
||||
WorkflowService.__post_process_field(task, field, data)
|
||||
|
||||
@staticmethod
|
||||
def __post_process_field(task, field, data):
|
||||
if field.has_property(Task.FIELD_PROP_DOC_CODE) and field.id in data:
|
||||
# This is generally handled by the front end, but it is possible that the file was uploaded BEFORE
|
||||
# the doc_code was correctly set, so this is a stop gap measure to assure we still hit it correctly.
|
||||
file_id = data[field.id]
|
||||
doc_code = task.workflow.script_engine.eval(field.get_property(Task.FIELD_PROP_DOC_CODE), data)
|
||||
file = db.session.query(FileModel).filter(FileModel.id == file_id).first()
|
||||
if(file):
|
||||
file.irb_doc_code = doc_code
|
||||
db.session.commit()
|
||||
# Set the doc code on the file.
|
||||
if field.has_property(Task.FIELD_PROP_FILE_DATA) and \
|
||||
field.get_property(Task.FIELD_PROP_FILE_DATA) in task.data:
|
||||
file_id = task.data[field.get_property(Task.FIELD_PROP_FILE_DATA)]
|
||||
data_store = DataStoreModel(file_id=file_id, key=field.id, value=task.data[field.id])
|
||||
db.session.add(data_store)
|
||||
else:
|
||||
# We have a problem, the file doesn't exist, and was removed, but it is still referenced in the data
|
||||
# At least attempt to clear out the data.
|
||||
data = {}
|
||||
if field.has_property(Task.FIELD_PROP_FILE_DATA) and \
|
||||
field.get_property(Task.FIELD_PROP_FILE_DATA) in data:
|
||||
file_id = data[field.get_property(Task.FIELD_PROP_FILE_DATA)]
|
||||
data_store = DataStoreModel(file_id=file_id, key=field.id, value=data[field.id])
|
||||
db.session.add(data_store)
|
||||
|
||||
@staticmethod
|
||||
def evaluate_property(property_name, field, task):
|
||||
|
|
|
@ -48,6 +48,20 @@ class TestStudyApi(BaseTest):
|
|||
response = json.loads(rv.get_data(as_text=True))
|
||||
self.assertEqual(True, response['result'])
|
||||
|
||||
def test_eval_returns_query(self):
|
||||
"""Assures that along with the result, we get the original data and expression.
|
||||
This can be useful if the calling client is caching results and needs to hash the expression and data
|
||||
when it gets returned."""
|
||||
data = '{"expression": "x.y==2", "data": {"x":{"y":2}}}'
|
||||
rv = self.app.put('/v1.0/eval',
|
||||
data=data, follow_redirects=True,
|
||||
content_type='application/json',
|
||||
headers=self.logged_in_headers())
|
||||
self.assert_success(rv)
|
||||
response = json.loads(rv.get_data(as_text=True))
|
||||
self.assertEqual("x.y==2", response['expression'])
|
||||
self.assertEqual({'x': {'y': 2}}, response['data'])
|
||||
|
||||
|
||||
def test_eval_expression_with_strings(self):
|
||||
"""Assures we can use python to process a value expression from the front end"""
|
||||
|
|
Loading…
Reference in New Issue