It is very difficult to invoke gateway-scoped functions. It requires putting a function in a specific project's Gateway Scripts message handler and then invoking it using a sort of clunky system.util.sendRequest call. This seems like it could all be handled in a more developer-friendly manner.
I propose a new system.util function like
system.util.gatewayInvocation(callback, *args, projectName=None, **kwargs)
that would generate a temporary Gateway Script
temp_{callback}
that invokes
return getattr(<system?>, payload['callback'])(*payload['args'], **payload['kwargs'])
and immediately calls it with something equivalent to
return system.util.sendRequest(projectName, 'temp_{}'.format(callback), {"args": args, "kwargs": kwargs})
.
callback
is either the callback object or a path to the callback (e.g.
"folder1.myScripts.myCallback"
)
args
is a list of ordered arguments for the callback
projectName
would be a project that is allowed to run gateway scripts (could take None to run from the invoking project by default)
kwargs
is a dict of keyword arguments for the callback
Additional functionality could involve saving the Gateway Script permanently (+kwarg save=None which will save the message handler if given a valid name string)
Could also link stdout temporarily so that print statements could be used
MORE DETAIL:
def gatewayInvocation(callback, *args, projectName=None, **kwargs):
if projectName == None:
projectName = system.future.currentProjectName()
text = """def messageHandler(payload):
system.future.addScriptsToGlobalsOrSomething()
return getattr(globals(), payload['callback'])(
*payload['args'], **payload['kwargs']))
"""
# Use context to localize the existence of the gateway script
with system.future.gatewayTempScriptContext(text):
result = system.util.sendMessage(projectName, callback,
{"args": args, "kwargs": kwargs})
I guess another way to give the developer an interface to this would be to hide it all in a context manager and do something like
with system.util.gatewayScriptContext():
call_my_function("arg1", kwarg2=4)
Although this would probably use some of the above logic under the hood.