"""Executable Python script for running Python actions. /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ """ import os import sys import codecs import traceback sys.path.append('../actionProxy') from actionproxy import ActionRunner, main, setRunner class PythonRunner(ActionRunner): def __init__(self): ActionRunner.__init__(self, '/action/__main__.py') self.fn = None self.mainFn = 'main' self.global_context = {} def initCodeFromString(self, message): # do nothing, defer to build step return True def build(self, message): binary = message['binary'] if 'binary' in message else False if not binary: code = message['code'] filename = 'action' elif os.path.isfile(self.source): with codecs.open(self.source, 'r', 'utf-8') as m: code = m.read() workdir = os.path.dirname(self.source) sys.path.insert(0, workdir) os.chdir(workdir) else: sys.stderr.write('Zip file does not include ' + os.path.basename(self.source) + '\n') return False try: filename = os.path.basename(self.source) self.fn = compile(code, filename=filename, mode='exec') if 'main' in message: self.mainFn = message['main'] # if the directory 'virtualenv' is extracted out of a zip file path_to_virtualenv = os.path.dirname(self.source) + '/virtualenv' if os.path.isdir(path_to_virtualenv): # activate the virtualenv using activate_this.py contained in the virtualenv activate_this_file = path_to_virtualenv + '/bin/activate_this.py' if os.path.exists(activate_this_file): with open(activate_this_file) as f: code = compile(f.read(), activate_this_file, 'exec') exec(code, dict(__file__=activate_this_file)) else: sys.stderr.write('Invalid virtualenv. Zip file does not include /virtualenv/bin/' + os.path.basename(activate_this_file) + '\n') return False exec(self.fn, self.global_context) return True except Exception: traceback.print_exc(file=sys.stderr, limit=0) return False def verify(self): return self.fn is not None def run(self, args, env): result = None try: os.environ = env self.global_context['param'] = args exec('fun = %s(param)' % self.mainFn, self.global_context) result = self.global_context['fun'] except Exception: traceback.print_exc(file=sys.stderr) if result and isinstance(result, dict): return (200, result) else: return (502, {'error': 'The action did not return a dictionary.'}) if __name__ == '__main__': setRunner(PythonRunner()) main()