def run(self): parser = self.get_argparse() self.args = args = parser.parse_args(sys.argv[1:]) self.console = Console() if args.subcommand not in ['install']: self.home_dir = args.home or os.environ.get( 'MOYA_SERVICE_HOME', None) or DEFAULT_HOME_DIR settings_path = os.path.join(self.home_dir, 'moya.conf') try: with io.open(settings_path, 'rt') as f: self.settings = SettingsContainer.read_from_file(f) except IOError: self.error('unable to read {}'.format(settings_path)) return -1 method_name = "run_" + args.subcommand.replace('-', '_') try: return getattr(self, method_name)() or 0 except CommandError as e: self.error(text_type(e)) except Exception as e: if args.debug: raise self.error(text_type(e))
def hashpassword(app, password): rounds = app.settings.get_int('rounds', 10000) scheme = text_type(app.settings.get('scheme', 'pbkdf2_sha512')).encode('utf-8') try: password_hash = moya_pwd_context.encrypt(password, scheme=scheme, rounds=rounds) except Exception as e: app.throw('moya.auth.password-hash-fail', text_type(e)) return password_hash
def hashpassword(app, password): rounds = app.settings.get_int('rounds', 10000) scheme = text_type(app.settings.get('scheme', 'pbkdf2_sha512')) try: password_hash = moya_pwd_context.encrypt(password, scheme=py2bytes(scheme), rounds=rounds) except Exception as e: app.throw('moya.auth.password-hash-fail', text_type(e)) return password_hash
def csrf_token(self): """Return a csrf token""" context = self.context user_id = text_type(context['.session_key'] or '') form_id = self.element.libid secret = text_type(self.element.archive.secret) raw_token = "{}{}{}".format(user_id, secret, form_id).encode('utf-8', 'ignore') m = hashlib.md5() m.update(raw_token) token_hash = m.hexdigest() return token_hash
def _cmp_seq(cls, v1, v2): """Compares a version sequence, padded with zeros to be the same size""" for a, b in zip_longest(v1, v2, fillvalue=0): # If types are different, treat them as text if type(a) != type(b): a = text_type(a) b = text_type(b) c = cmp(a, b) if c: return c return 0
def hashpassword(app, password): if password is None: return None rounds = app.settings.get_int("rounds", 10000) scheme = text_type(app.settings.get("scheme", "pbkdf2_sha512")) try: password_hash = moya_pwd_context.encrypt(password, scheme=py2bytes(scheme), rounds=rounds) except Exception as e: app.throw("moya.auth.password-hash-fail", text_type(e)) return password_hash
def base(self): if self.release: return "{}.{}-{}".format( self.major, self.minor, '.'.join(text_type(r) for r in self.release)) else: return "{}.{}".format(self.major, self.minor)
def __init__(self, home_dir=None): super(Service, self).__init__() self.changes = {} self.home_dir = home_dir = ( os.environ.get("MOYA_SERVICE_HOME", None) or DEFAULT_HOME_DIR ) settings_path = os.path.join(home_dir, "moya.conf") try: with io.open(settings_path, "rt") as f: self.settings = SettingsContainer.read_from_file(f) except IOError: self.error("unable to read {}".format(settings_path)) return -1 logging_setting = self.settings.get("projects", "logging", "logging.ini") logging_path = os.path.join(self.home_dir, logging_setting) try: init_logging(logging_path) except Exception as e: log.error("unable to initialize logging from '%s'", logging_path) sys.stderr.write( "unable to initialize logging from '{}' ({})\n".format(logging_path, e) ) return -1 log.debug("read conf from %s", settings_path) log.debug("read logging from %s", logging_path) temp_dir_root = self.settings.get("service", "temp_dir", tempfile.gettempdir()) self.debug_memory = objgraph and self.settings.get_bool( "service", "debug_memory", False ) self.temp_dir = os.path.join(temp_dir_root, "moyasrv") try: os.makedirs(self.temp_dir) except OSError: pass for path in self._get_projects(self.settings, self.home_dir): log.debug("reading project settings %s", path) try: self.add_project(path) except: log.exception("error adding project from '%s'", path) for server_name in self.servers: path = os.path.join(self.temp_dir, "{}.changes".format(server_name)) try: if not os.path.exists(path): with open(path, "wb"): pass except IOError as e: sys.stderr.write("{}\n".format(text_type(e))) return -1 self.changes[server_name] = os.path.getmtime(path) self.build_all()
def test_lazystr(self): s = tools.lazystr(lambda: 'foo') assert text_type(s) == 'foo' s = tools.lazystr(lambda: 'foo') assert len(s) == 3 s = tools.lazystr(lambda: 'foo') assert s.upper() == 'FOO'
def test_lazystr(self): s = tools.lazystr(lambda: "foo") assert text_type(s) == "foo" s = tools.lazystr(lambda: "foo") assert len(s) == 3 s = tools.lazystr(lambda: "foo") assert s.upper() == "FOO"
def get_oauth_profile(app, provider, credentials, verifier): context = moya.pilot.context client_id, client_secret = get_credentials(provider, credentials) resource_owner_key = context['.session.oauth1.resource_owner.key'] resource_owner_secret = context['.session.oauth1.resource_owner.secret'] resources = provider.get('resources', {}) session = OAuth1Session(client_id, client_secret=client_secret, resource_owner_key=resource_owner_key, resource_owner_secret=resource_owner_secret, verifier=verifier) access_token_url = provider['access_token_url'] try: oauth_tokens = session.fetch_access_token(access_token_url) except Exception as e: app.throw('moya.logins.access-fail', text_type(e)) info = {} for scope, scope_url in sorted(resources.items()): try: response = session.get(scope_url) except Exception as e: app.throw('moya.logins.get-scope-fail', text_type(e), diagnosis="There may be a connectivity issue getting scope information.", scope=scope, scope_url=scope_url) try: info[scope] = scope_data = response.json() #if(context['.debug']): # context['.console'].obj(context, scope_data) except: pass provider_profile = provider.get('profile', {}) profile = {} context['_oauth_info'] = info with context.frame('_oauth_info'): for k, v in provider_profile.items(): try: profile[k] = context.eval(v) except: pass return {'profile': profile, 'info': info}
def __init__(self, home_dir=None): super(Service, self).__init__() self.changes = {} self.home_dir = home_dir = os.environ.get('MOYA_SERVICE_HOME', None) or DEFAULT_HOME_DIR settings_path = os.path.join(home_dir, 'moya.conf') try: with io.open(settings_path, 'rt') as f: self.settings = SettingsContainer.read_from_file(f) except IOError: self.error('unable to read {}'.format(settings_path)) return -1 logging_setting = self.settings.get('projects', 'logging', 'logging.ini') logging_path = os.path.join(self.home_dir, logging_setting) try: init_logging(logging_path) except Exception as e: log.error("unable to initialize logging from '%s'", logging_path) sys.stderr.write( "unable to initialize logging from '{}' ({})\n".format( logging_path, e)) return -1 log.debug('read conf from %s', settings_path) log.debug('read logging from %s', logging_path) temp_dir_root = self.settings.get('service', 'temp_dir', tempfile.gettempdir()) self.temp_dir = os.path.join(temp_dir_root, 'moyasrv') try: os.makedirs(self.temp_dir) except OSError: pass for path in self._get_projects(self.settings, self.home_dir): log.debug('reading project settings %s', path) try: self.add_project(path) except: log.exception("error adding project from '%s'", path) for server_name in self.servers: path = os.path.join(self.temp_dir, "{}.changes".format(server_name)) try: if not os.path.exists(path): with open(path, 'wb'): pass except IOError as e: sys.stderr.write("{}\n".format(text_type(e))) return -1 self.changes[server_name] = os.path.getmtime(path) self.build_all()
def escape(text): """Escape text for inclusion in html""" return ( text_type(text) .replace("&", "&") .replace("<", "<") .replace(">", ">") .replace('"', """) .replace("'", "'") )
def __init__(self, home_dir=None): super(Service, self).__init__() self.changes = {} self.home_dir = home_dir = os.environ.get('MOYA_SRV_HOME', None) or DEFAULT_HOME_DIR settings_path = os.path.join(home_dir, 'moya.conf') try: with io.open(settings_path, 'rt') as f: self.settings = SettingsContainer.read_from_file(f) except IOError: self.error('unable to read {}'.format(settings_path)) return -1 logging_setting = self.settings.get('projects', 'logging', 'logging.ini') logging_path = os.path.join(self.home_dir, logging_setting) try: init_logging(logging_path) except Exception as e: log.exception('error reading logging') log.debug('read conf from %s', settings_path) log.debug('read logging from %s', logging_path) temp_dir_root = self.settings.get('service', 'temp_dir', tempfile.gettempdir()) self.temp_dir = os.path.join(temp_dir_root, 'moyasrv') try: os.makedirs(self.temp_dir) except OSError: pass for path in self._get_projects(): log.debug('reading project settings %s', path) try: self.add_project(path) except: log.exception("error adding project from '%s'", path) for server_name in self.servers: path = os.path.join(self.temp_dir, "{}.changes".format(server_name)) try: if not os.path.exists(path): with open(path, 'wb'): pass except IOError as e: sys.stderr.write("{}\n".format(text_type(e))) return -1 self.changes[server_name] = os.path.getmtime(path) self.build_all()
def get_value(self, context): app, lib, ref = self.get_parameters(context, 'app', 'lib', 'ref') if app is not None: app = self.archive.get_app(app) if lib is not None: lib = self.archive.get_lib(lib) ref = text_type(ref) try: element = self.archive.get_element(ref, app=app, lib=lib or None) except Exception as e: self.throw('qualify-elementref.not-found', 'unable to look up element ({})'.format(e)) element_ref = "{}#{}".format(element.app.name, element.element.libname) return element_ref
def run(self): parser = self.get_argparse() self.args = args = parser.parse_args(sys.argv[1:]) self.console = Console() self.home_dir = args.home or os.environ.get('MOYA_SRV_HOME', None) or DEFAULT_HOME_DIR settings_path = os.path.join(self.home_dir, 'moya.conf') try: with io.open(settings_path, 'rt') as f: self.settings = SettingsContainer.read_from_file(f) except IOError: self.error('unable to read {}'.format(settings_path)) return -1 method_name = "run_" + args.subcommand.replace('-', '_') try: return getattr(self, method_name)() or 0 except CommandError as e: self.error(text_type(e)) except Exception as e: if args.debug: raise self.error(text_type(e))
def logic(self, context): form, dst = self.get_parameters(context, 'src', 'dst') form_data = form.data dst_obj = context[dst] if not hasattr(dst_obj, 'items'): self.throw( 'moya.forms.bad-dst', "Object referenced by 'dst' must be dict or other mapping type (not {})" .format(to_expression(context, dst_obj))) if dst: field_names = self.fields(context) if field_names is None: fields = list(form.fields) else: fields = [form.fields[name] for name in field_names] for field in fields: applyers = form.field_applyers[field.name] if applyers: for apply_field in applyers: with self.closure_call( context, form.app, apply_field.data, form=form, object=dst_obj, values=form.data, value=form.data[field.name]) as call: yield logic.DeferNodeContents(apply_field.element) else: with context.frame(dst): field_dst = field.dst if dst: value = form_data.get(field.name, None) try: context[field_dst] = value except Exception as e: diagnosis_msg = "Check you are setting this field to an appropriate value." self.throw( 'moya.forms.apply-fail', "unable to set for field '{}' to {}". format(dst, context.to_expr(value)), diagnosis=diagnosis_msg, info={ 'field': field.name, 'error': text_type(e) })
def run_restart(self): name = self.args.name if not self.project_exists(name): self.error("no project '{}'".format(name)) temp_dir = os.path.join(self.settings.get('service', 'temp_dir', tempfile.gettempdir()), 'moyasrv') try: os.makedirs(temp_dir) except OSError: pass change_path = os.path.join(temp_dir, "{}.changes".format(name)) try: with open(change_path, 'a'): os.utime(change_path, None) except IOError as e: sys.stderr.write("{}\n".format(text_type(e))) return -1
def fetch_oauth2_token(app, provider, credentials, redirect_uri): client_id, client_secret = get_credentials(provider, credentials) context = moya.pilot.context session = OAuth2Session(client_id, state=context['.session.oauth2.state'], redirect_uri=redirect_uri) try: token = session.fetch_token(provider['token_url'], client_secret=client_secret, authorization_response=context['.request.url']) except InsecureTransportError as e: moya.pilot.throw('moya.logins.insecure-transport', text_type(e), diagnosis="You can disable the requirement for SSL during development with the following:\n\n**export OAUTHLIB_INSECURE_TRANSPORT=1**") except Exception as e: moya.pilot.throw('moya.logins.fail', "failed to fetch oauth2 token ({})".format(e)) return token
def run_restart(self): name = self.args.name if not self.project_exists(name): self.error("no project '{}'".format(name)) temp_dir = os.path.join( self.settings.get('service', 'temp_dir', tempfile.gettempdir()), 'moyasrv') try: os.makedirs(temp_dir) except OSError: pass change_path = os.path.join(temp_dir, "{}.changes".format(name)) try: with open(change_path, 'a'): os.utime(change_path, None) except IOError as e: sys.stderr.write("{}\n".format(text_type(e))) return -1
def logic(self, context): form, dst = self.get_parameters(context, 'src', 'dst') form_data = form.data dst_obj = context[dst] if not hasattr(dst_obj, 'items'): self.throw('moya.forms.bad-dst', "Object referenced by 'dst' must be dict or other mapping type (not {})".format(to_expression(context, dst_obj))) if dst: field_names = self.fields(context) if field_names is None: fields = list(form.fields) else: fields_map = form.fields_map fields = [fields_map[name] for name in field_names] for field in fields: applyers = form.field_applyers[field.name] if applyers: for apply_field in applyers: with self.closure_call(context, form.app, apply_field.data, form=form, object=dst_obj, values=form.data, value=form.data[field.name]) as call: yield logic.DeferNodeContents(apply_field.element) else: with context.frame(dst): field_dst = field.dst if field_dst: value = form_data.get(field.name, None) try: context[field_dst] = value except Exception as e: diagnosis_msg = "Check you are setting this field to an appropriate value." self.throw('moya.forms.apply-fail', "unable to set field '{}' to {}".format(dst, context.to_expr(value)), diagnosis=diagnosis_msg, info={'field': field.name, 'error': text_type(e)})
def get_oauth2_profile(app, provider, credentials, token): client_id, secret_id = get_credentials(provider, credentials) context = moya.pilot.context scope = provider.get('scope', []) resources = provider.get('resources', {}) session = OAuth2Session(client_id, scope=scope, token=token) info = {} for scope, scope_url in sorted(resources.items()): try: response = session.get(scope_url) except Exception as e: app.throw('moya.logins.get-scope-fail', text_type(e), diagnosis="There may be a connectivity issue getting scope information.", scope=scope, scope_url=scope_url) try: info[scope] = scope_data = response.json() #if(context['.debug']): # context['.console'].obj(context, scope_data) except: pass provider_profile = provider.get('profile', {}) profile = {} context['_oauth_info'] = info with context.frame('_oauth_info'): for k, v in provider_profile.items(): try: profile_value = context.eval(v) except: pass else: if not is_missing(profile_value): profile[k] = profile_value return {'profile': profile, 'info': info}
def get_oauth2_profile(app, provider, credentials, token): client_id, secret_id = get_credentials(provider, credentials) context = moya.pilot.context scope = provider.get('scope', []) resources = provider.get('resources', {}) session = OAuth2Session(client_id, scope=scope, token=token) info = {} for scope, scope_url in sorted(resources.items()): try: response = session.get(scope_url) except Exception as e: app.throw( 'moya.logins.get-scope-fail', text_type(e), diagnosis= "There may be a connectivity issue getting scope information.", scope=scope, scope_url=scope_url) try: info[scope] = scope_data = response.json() #if(context['.debug']): # context['.console'].obj(context, scope_data) except: pass provider_profile = provider.get('profile', {}) profile = {} context['_oauth_info'] = info with context.frame('_oauth_info'): for k, v in provider_profile.items(): try: profile_value = context.eval(v) except: pass else: if not is_missing(profile_value): profile[k] = profile_value return {'profile': profile, 'info': info}
def fetch_oauth2_token(app, provider, credentials, redirect_uri): client_id, client_secret = get_credentials(provider, credentials) context = moya.pilot.context session = OAuth2Session(client_id, state=context['.session.oauth2.state'], redirect_uri=redirect_uri) try: token = session.fetch_token( provider['token_url'], client_secret=client_secret, authorization_response=context['.request.url']) except InsecureTransportError as e: moya.pilot.throw( 'moya.logins.insecure-transport', text_type(e), diagnosis= "You can disable the requirement for SSL during development with the following:\n\n**export OAUTHLIB_INSECURE_TRANSPORT=1**" ) except Exception as e: moya.pilot.throw('moya.logins.fail', "failed to fetch oauth2 token ({})".format(e)) return token
def get_frame(self): """Get the current frame""" return text_type(self._stack.index)
def __str__(self): return text_type(self.obj)
def __repr__(self): return text_type(self.value)
def normalized(self): return "{}{}".format(self.name, ''.join(c + text_type(v) for c, v in self.comparisons))
def escape(text): """Escape text for inclusion in html""" return text_type(text).replace('&', '&').replace('<', '<').replace('>', '>').replace('"', '"').replace("'", "'")
def text(self): text = ".".join(text_type(n) for n in self.number) if self.release: text += "-{}".format('.'.join(text_type(t) for t in self.release)) return text
def linebreaks(text): """Replace new lines with <br>""" html = "<br>\n".join(escape(text_type(text)).splitlines()) return html
def lib_finalize(self, context): (interface, call_macro, name, group, description) = self.get_parameters(context, "interface", "call", "name", "group", "description") if interface is None: try: interface = self.get_ancestor( (namespaces.jsonrpc, "interface")) except: raise errors.ElementError( "this tag must be inside an <interface>, or specify the 'interface' attribute", element=self, ) else: try: interface = self.get_element(interface).element except: raise errors.ElementError( "element '{}' isn't an <interface>".format(interface), element=self) params = {} for sig_tag in self.children((namespaces.jsonrpc, "signature")): param_tags = sig_tag.children((namespaces.jsonrpc, "parameter")) break else: param_tags = self.children((namespaces.jsonrpc, "parameter")) for param_tag in param_tags: try: (param_name, _type, default, null, required) = param_tag.get_parameters(context, "name", "type", "default", "null", "required") except Exception as e: raise errors.ElementError(text_type(e), element=param_tag) if param_tag.has_parameter("default"): required = False doc = context.sub(param_tag.text.strip()) _param = params[param_name] = Param( param_name, _type, default=default, required=required, null=null, doc=doc, ) # if not required: # try: # _param.make_default(context) # except InvalidParamDefault: # raise errors.ElementError("default '{}' is invalid for type '{}'".format(default, _type), # element=param_tag) doc = self.get_child("doc") if doc is not None: doc_text = context.sub(doc.text) doc_text = textwrap.dedent(doc_text) else: doc_text = None interface.register_method( name, self, macro=call_macro, group=group, params=params, description=description, doc=doc_text, )
def normalized(self): return "{}{}".format( self.name, ''.join(c + text_type(v) for c, v in self.comparisons))
def base(self): if self.release: return "{}.{}-{}".format(self.major, self.minor, '.'.join(text_type(r) for r in self.release)) else: return "{}.{}".format(self.major, self.minor)
def escape(text): """Escape text for inclusion in html""" return text_type(text).replace('&', '&').replace('<', '<').replace( '>', '>').replace('"', '"').replace("'", "'")
def run(self, context): """Generate a response for either a GET or a POST""" request = context[".request"] app = context.get(".app", None) interface_id = "<interface {}#{}>".format(app.name, self.libname) if request.method == "GET": render_container = RenderContainer.create( app, template="moya.jsonrpc/interface.html") render_container["interface"] = self context["_return"] = render_container return if request.method != "POST": return context[".jsonrpc"] = {"request": {}} try: req = json.loads(request.body.decode("utf-8")) except Exception as e: log.debug("%s badly formatted JSONRPC request: %s", interface_id, e) response = self.make_error(None, False, code=ErrorCode.parse_error, message=text_type(e)) raise logic.EndLogic(response) batch = isinstance(req, list) responses = [] for response in self.process_request(context, req): if response is None: # Notification continue elif isinstance(response, ErrorResponse): # Problem with request responses.append(response) elif isinstance(response, CallMethod): # Request good, do call method, params, req_id, notification = response log.debug( "%s %s '%s' with %s", interface_id, "notify" if notification else "call", method.name, lazystr(to_expression, context, params, 80), ) try: params = response.method.process_params(context, params) except ParamError as e: response = ErrorResponse(ErrorCode.invalid_params, text_type(e), id=req_id) self.log_result(context, response) responses.append(response) continue def do_call(element, app, params): try: return_value = self.archive.call( element.libid, context, app, **params) except Exception as e: if isinstance(getattr(e, "original", None), MoyaException): moya_exc = e.original if moya_exc.type == "jsonrpc.error": return RPCErrorReturn( moya_exc.info["code"], moya_exc.info["message"], moya_exc.info["data"], ) error_message = "exception '{}' in rpc call to {}".format( e, method) if hasattr(e, "moya_trace"): log.error(error_message) if context[".debug"] and context[".console"]: context[".console"].obj(context, e) else: error_message = "{}\n{}".format( error_message, e.moya_trace) log.error(error_message) else: context[".console"].obj(context, e) log.exception(error_message) response = ErrorResponse( ErrorCode.internal_error, "internal error -- this error has been logged", id=req_id, ) return response else: return return_value return_value = do_call(method.element, app, params) if method.macro is not None and not isinstance( return_value, (RPCResponse, RPCErrorReturn)): try: macro_app, macro_element = self.get_element( method.macro, app) except Exception as e: log.error("%s no macro called '%s'", interface_id, method.macro) return_value = ErrorResponse( ErrorCode.internal_error, "internal error -- this error has been logged", id=req_id, ) else: return_value = do_call(macro_element, app, params) if isinstance(return_value, RPCResponse): self.log_result(context, return_value) responses.append(return_value) continue if notification: continue if isinstance(return_value, RPCErrorReturn): code, message, data = return_value if code.isdigit(): code = int(code) else: try: code = int(self.errors[code]) if not message: message = self.errors[code].description except Exception as e: log.error( "invalid error code '{}' -- defaulting to 'internal_error'" .format(code)) code = ErrorCode.internal_error message = ErrorCode.to_str[code] return_value = RPCErrorReturn(code, message, data) response = ErrorResponse(code, message, data=data, id=req_id) self.log_result(context, response) else: # Check the response is serializable try: moyajson.dumps(return_value) except Exception as e: log.error(text_type(e)) response = ErrorResponse( ErrorCode.internal_error, "internal error -- server was unable to serialize the response", id=req_id, ) self.log_result(context, response) else: response = SuccessResponse(return_value, req_id) self.log_result(context, return_value) responses.append(response) if not responses: raise logic.EndLogic( Response(content_type=b"application/json" if PY2 else "application/json")) try: if batch: response_json = moyajson.dumps(responses, indent=4) else: response_json = moyajson.dumps(responses[0], indent=4) except Exception as e: log.exception("error serializing response") error_response = ErrorResponse( ErrorCode.internal_error, "server was unable to generate a response -- this error has been logged", id=None, ) response_json = moyajson.dumps(error_response) response = Response( content_type=b"application/json" if PY2 else "application/json", body=response_json, ) raise logic.EndLogic(response) yield # Because this method should be a generator
def run(self, context): """Generate a response for either a GET or a POST""" request = context['.request'] app = context.get('.app', None) interface_id = "<interface {}#{}>".format(app.name, self.libname) if request.method == "GET": render_container = RenderContainer.create(app, template="moya.jsonrpc/interface.html") render_container['interface'] = self context['_return'] = render_container return if request.method != "POST": return context['.jsonrpc'] = {"request": {}} try: req = json.loads(request.body.decode('utf-8')) except Exception as e: log.debug("%s badly formatted JSONRPC request: %s", interface_id, e) response = self.make_error(None, False, code=ErrorCode.parse_error, message=text_type(e)) raise logic.EndLogic(response) batch = isinstance(req, list) responses = [] for response in self.process_request(context, req): if response is None: # Notification continue elif isinstance(response, ErrorResponse): # Problem with request responses.append(response) elif isinstance(response, CallMethod): # Request good, do call method, params, req_id, notification = response log.debug("%s %s '%s' with %s", interface_id, 'notify' if notification else 'call', method.name, lazystr(to_expression, context, params, 80)) try: params = response.method.process_params(params) except ParamError as e: response = ErrorResponse(ErrorCode.invalid_params, text_type(e), id=req_id) self.log_result(context, response) responses.append(response) continue def do_call(element, app, params): try: return_value = self.archive.call(element.libid, context, app, **params) except Exception as e: if isinstance(e.original, MoyaException): moya_exc = e.original if moya_exc.type == "jsonrpc.error": return RPCErrorReturn(moya_exc.info['code'], moya_exc.info['message'], moya_exc.info['data']) error_message = "exception '{}' in rpc call to {}".format(e, method) if hasattr(e, 'moya_trace'): log.error(error_message) if context['.debug'] and context['.console']: context['.console'].obj(context, e) else: error_message = "{}\n{}".format(error_message, e.moya_trace) log.error(error_message) else: context['.console'].obj(context, e) log.exception(error_message) response = ErrorResponse(ErrorCode.internal_error, 'internal error -- this error has been logged', id=req_id) return response else: return return_value return_value = do_call(method.element, app, params) if method.macro is not None and not isinstance(return_value, (RPCResponse, RPCErrorReturn)): try: macro_app, macro_element = self.get_element(method.macro, app) except Exception as e: log.error("%s no macro called '%s'", interface_id, method.macro) return_value = ErrorResponse(ErrorCode.internal_error, "internal error -- this error has been logged", id=req_id) else: return_value = do_call(macro_element, app, params) if isinstance(return_value, RPCResponse): self.log_result(context, return_value) responses.append(return_value) continue if notification: continue if isinstance(return_value, RPCErrorReturn): code, message, data = return_value if code.isdigit(): code = int(code) else: try: code = int(self.errors[code]) if not message: message = self.errors[code].description except Exception as e: log.error("invalid error code '{}' -- defaulting to 'internal_error'".format(code)) code = ErrorCode.internal_error message = ErrorCode.to_str[code] return_value = RPCErrorReturn(code, message, data) response = ErrorResponse(code, message, data=data, id=req_id) self.log_result(context, response) else: # Check the response is serializable try: moyajson.dumps(return_value) except Exception as e: log.error(text_type(e)) response = ErrorResponse(ErrorCode.internal_error, 'internal error -- server was unable to serialize the response', id=req_id) self.log_result(context, response) else: response = SuccessResponse(return_value, req_id) self.log_result(context, return_value) responses.append(response) if not responses: raise logic.EndLogic(Response(content_type=b'application/json' if PY2 else 'application/json')) try: if batch: response_json = moyajson.dumps(responses, indent=4) else: response_json = moyajson.dumps(responses[0], indent=4) except Exception as e: log.exception("error serializing response") error_response = ErrorResponse(ErrorCode.internal_error, "server was unable to generate a response -- this error has been logged", id=None) response_json = moyajson.dumps(error_response) response = Response(content_type=b'application/json' if PY2 else 'application/json', body=response_json) raise logic.EndLogic(response) yield # Because this method should be a generator