def process_action_input(cls, context, input): input_error = {} for key, argument in context.action.arguments.items(): value_provided = key in input if not value_provided and argument._default is not None: # this must be here because the default value will be ignored, see line 99 value_provided = True value = argument._default else: value = input.get(key) if argument and hasattr(argument, 'format'): try: if not value_provided and not argument._required: continue # skip the .format only if the value was not provided, and if the argument is not required value = argument.format(value) if hasattr(argument, '_validator') and argument._validator: # _validator is a custom function that is available by ndb. argument._validator(argument, value) context.input[key] = value except ndb.PropertyError as e: if e.message not in input_error: input_error[e.message] = [] input_error[e.message].append(key) # We group argument exceptions based on exception messages. except Exception as e: # If this is not defined it throws an error. if 'non_property_error' not in input_error: input_error['non_property_error'] = [] input_error['non_property_error'].append(key) # Or perhaps, 'non_specific_error', or something simmilar. util.logger(e, 'exception') if len(input_error): raise InputError(input_error)
def run(cls, input): pr = cProfile.Profile() pr.enable() util.logger('Payload: %s' % input) context = Context() cls.process_blob_input(context, input) # This is the most efficient strategy to handle blobs we can think of! try: cls.init() cls.get_models(context) cls.get_model(context, input) cls.get_action(context, input) cls.process_action_input(context, input) cls.execute_action(context, input) except Exception as e: throw = True if isinstance(e.message, dict): # Here we handle our exceptions. for key, value in e.message.items(): context.error(key, value) throw = False if isinstance(e, datastore_errors.Timeout): context.error('transaction', 'timeout') throw = False if isinstance(e, datastore_errors.TransactionFailedError): context.error('transaction', 'failed') throw = False if throw: raise # Here we raise all other unhandled exceptions! finally: cls.process_blob_output(context) # This is the most efficient strategy to handle blobs we can think of! pr.disable() s = StringIO.StringIO() sortby = 'cumulative' ps = pstats.Stats(pr, stream=s).sort_stats(sortby) ps.print_stats() log = s.getvalue() class PerformanceLog(ndb.BaseModel): log = ndb.TextProperty() PerformanceLog(log=log, id='endpoint.action.%s' % context.action.key.id()).put() return context.output
def execute_action(cls, context, input): util.logger('Execute action: %s.%s' % (context.model.__name__, context)) util.logger('Arguments: %s' % (context.input)) def execute_plugins(plugins): for plugin in plugins: util.logger('Running plugin: %s.%s' % (plugin.__module__, plugin.__class__.__name__)) plugin.run(context) if hasattr(context.model, 'get_plugin_groups') and callable(context.model.get_plugin_groups): try: plugin_groups = context.model.get_plugin_groups(context.action) if len(plugin_groups): for group in plugin_groups: if len(group.plugins): if group.transactional: ndb.transaction(lambda: execute_plugins(group.plugins), xg=True) else: execute_plugins(group.plugins) except event.TerminateAction as e: pass except Exception as e: raise
def process_blob_output(cls, context): if len(context.blob_unused): util.logger('DELETED BLOBS: %s' % [str(b) for b in context.blob_unused]) blobstore.delete(context.blob_unused) context.blob_unused = []
def execute_plugins(plugins): for plugin in plugins: util.logger('Running plugin: %s.%s' % (plugin.__module__, plugin.__class__.__name__)) plugin.run(context)