I need my server-side code to execute a funcion whose code is stored (as a python file) in a media column (or, that is the same, in a string).
This server code is triggered in an HTTP API endpoint.
This is needed because that function is a validation function that must be defined in configuration, and is not know in advance.
Customer A may have its own validation function, customer B its own, etc etc.
Using uplink, I was able to do that with this code:
evaluation_function_file = row['answers_script'] # db column with media object .py file
print("Evaluation script:")
print(evaluation_function_file.get_bytes().decode('utf-8'))
with tempfile.TemporaryDirectory() as tmpdirname:
print('Running in temporary directory:', tmpdirname)
filename = tmpdirname + '\\my_func.py'
anvil.media.write_to_file(media=evaluation_function_file,filename=filename)
sys.path.append(tmpdirname)
import my_func
result = my_func.my_func(questions_list=questions_list)
sys.path.pop()
print("result:", result )
This code assumes that the function inside my_func.py is defined as
def my_func():
This code works on Uplink but does not work in Anvil server environment,
I get this app log:
Running in temporary directory:
/tmp/tmpi7_swy8c
ModuleNotFoundError: No module named 'my_func'
at callback, line 102
called from /downlink/anvil/_server.py, line 1288
Then I tried to avoid dynamic python files and keep it all in RAM:
evaluation_function_file = row['answers_script'] # db column with media object .py file
function_code_str = evaluation_function_file.get_bytes().decode('utf-8')
print("Evaluation script:")
print(evaluation_function_file.get_bytes().decode('utf-8'))
exec(function_code_str)
result = my_func(questions_list=questions_list)
print("result:", result )
But that’s not working either.
I get this app log:
NameError: name 'my_func' is not defined
at callback, line 107
called from /downlink/anvil/_server.py, line 1288
BTW this second method doesn’t work in Uplink too.
Is there a way to do what I need?
That is: define a function whose code is determined at run-time getting it from a table-column (or, more in general, from a string) and call that function.
Or, is there some other approach to the problem, that is: how to validate a list of answers against a user-defined, runtime-defined function?
Thanks