def request_params(request): try: params = NestedMultiDict(request.GET, request.POST) except UnicodeDecodeError: request.errors.add('body', 'data', 'could not decode params') request.errors.status = 422 raise json_error(request.errors) except Exception, e: request.errors.add('body', str(e.__class__.__name__), str(e)) request.errors.status = 422 raise json_error(request.errors)
def put(self): """Updates or creates an item.""" # grab the id id_ = int(self.request.matchdict[self.match_key]) # is that an existing item ? item = self.dbsession.query(self.mapping) item = item.filter(self.mapping.id==id_).first() if item is None: # then we can post return self.post() # we can update new_item = self.serialize() if len(self.request.errors) > 0: return json_error(self.request.errors) for key in self.cols: if key == self.primary_key: continue if key not in new_item: continue new_value = new_item[key] value = getattr(item, key) if new_value != value: setattr(item, key, new_value) self.dbsession.commit() # needed ? return {'status': 'OK'}
def create_model_definition(request): """Creates a model definition. In addition to checking that the data sent complies with what's expected (the schema), we check on case of a modification that the token is present and valid. """ modelname = request.matchdict['modelname'] results = db_model_token(request.db)[modelname] tokens = [t.value for t in results] if len(tokens) > 0: token = tokens[0] if token != request.GET.get('token'): # provided token does not match request.errors.add('query', 'token', 'invalid token for model %s' % modelname) request.errors.status = 403 return json_error(request.errors) else: # Generate a unique token token = os.urandom(8).encode('hex') token_doc = {'type': 'token', 'token': token, 'model': modelname} request.db.save(token_doc) model_doc = { 'type': 'definition', 'model': modelname, 'definition': json.loads(request.body) } request.db.save(model_doc) # save to couchdb return {'token': token}
def validate_json_data(request): try: json = request.json_body except ValueError, e: request.errors.add('body', 'data', e.message) request.errors.status = 422 raise json_error(request.errors)
def call_service(func, api_kwargs, context, request): """Wraps the request and the response, once a route does match.""" # apply validators for validator in api_kwargs.get('validators', []): validator(request) if len(request.errors) > 0: return json_error(request.errors) return func(request)
def post(self): """Creates an item""" # serialize the request into a PUT-able item item = self.serialize() if len(self.request.errors) > 0: return json_error(self.request.errors) # grab the id id_ = int(self.request.matchdict[self.match_key]) # create a User object now item = self.mapping(id=id_, **item) self.dbsession.add(item) try: self.dbsession.commit() # needed ? except IntegrityError, e: # that id is taken already probably, self.request.errors.add('body', 'item', e.message) self.dbsession.rollback() return json_error(self.request.errors)
def catch_all_error_handler(exc, request): log.exception('Unexpected error: {}'.format(exc)) show_debugger_for_errors = \ request.registry.settings.get('show_debugger_for_errors', '') if show_debugger_for_errors == 'true': raise exc request.errors = Errors(500) request.errors.add('body', 'unexpected error', 'please consult the server logs') return json_error(request)
def catch_all_error_handler(exc, request): log.exception('Unexpected error: {}'.format(exc)) show_debugger_for_errors = \ request.registry.settings.get('show_debugger_for_errors', '') if show_debugger_for_errors == 'true': raise exc request.errors = Errors(500) request.errors.add( 'body', 'unexpected error', 'please consult the server logs') return json_error(request)
def error_handler(errors, request_params=True): params = {'ERROR_STATUS': errors.status} if request_params: if errors.request.params: params['PARAMS'] = str(dict(errors.request.params)) if errors.request.matchdict: for x, j in errors.request.matchdict.items(): params[x.upper()] = j LOGGER.info('Error on processing request "{}"'.format( dumps(errors, indent=4)), extra=context_unpack(errors.request, {'MESSAGE_ID': 'error_handler'}, params)) return json_error(errors)
def error_handler(errors, request_params=True): params = {"ERROR_STATUS": errors.status} if request_params: params["ROLE"] = str(errors.request.authenticated_role) if errors.request.params: params["PARAMS"] = str(dict(errors.request.params)) if errors.request.matchdict: for x, j in errors.request.matchdict.items(): params[x.upper()] = j LOGGER.info( 'Error on processing request "{}"'.format(dumps(errors, indent=4)), extra=context_unpack(errors.request, {"MESSAGE_ID": "error_handler"}, params), ) return json_error(errors)
def raise_invalid(self, location: str = 'body', name: str = '', description: str = '', **kwargs): """Raise a 400 error. :param location: location in request (e.g. ``'querystring'``) :param name: field name :param description: detailed description of validation error """ request = self.request request.errors.add(location, name, description, **kwargs) return json_error(request)
def inner(request): if not hasattr(request, 'validated'): setattr(request, 'validated', {}) if not hasattr(request, 'errors'): setattr(request, 'errors', Errors()) if not hasattr(request, 'info'): setattr(request, 'info', {}) for validator in self.validators: validator(request=request) if len(request.errors) > 0: return json_error(request) return func(request)
def call_service(func, api_kwargs, context, request): """Wraps the request and the response, once a route does match.""" # apply validators for validator in api_kwargs.get('validators', []): validator(request) if len(request.errors) > 0: return json_error(request.errors) res = dict(result=func(request), status='ok') request.response.headers['Cache-Control'] = 'no-store' request.response.headers['Expires'] = '-1' return res
def error_handler(errors, request_params=True): params = { 'ERROR_STATUS': errors.status } if request_params: params['ROLE'] = str(errors.request.authenticated_role) if errors.request.params: params['PARAMS'] = str(dict(errors.request.params)) if errors.request.matchdict: for x, j in errors.request.matchdict.items(): params[x.upper()] = j errors.request.registry.notify(ErrorDesctiptorEvent(errors, params)) LOGGER.info('Error on processing request "{}"'.format(dumps(errors, indent=4)), extra=context_unpack(errors.request, {'MESSAGE_ID': 'error_handler'}, params)) return json_error(errors)
def error_handler(errors, request_params=True): params = {'ERROR_STATUS': errors.status} if request_params: params['ROLE'] = str(errors.request.authenticated_role) if errors.request.params: params['PARAMS'] = str(dict(errors.request.params)) if errors.request.matchdict: for x, j in errors.request.matchdict.items(): params[x.upper()] = j errors.request.registry.notify(ErrorDesctiptorEvent(errors, params)) LOGGER.info('Error on processing request "{}"'.format( dumps(errors, indent=4)), extra=context_unpack(errors.request, {'MESSAGE_ID': 'error_handler'}, params)) return json_error(errors)
def error_handler(request, request_params=True): errors = request.errors params = {"ERROR_STATUS": errors.status} if request_params: params["ROLE"] = str(request.authenticated_role) if request.params: params["PARAMS"] = str(dict(request.params)) if request.matchdict: for x, j in request.matchdict.items(): params[x.upper()] = j request.registry.notify(ErrorDescriptorEvent(request, params)) LOGGER.info( 'Error on processing request "{}"'.format(dumps(errors, indent=4)), extra=context_unpack(request, {"MESSAGE_ID": "error_handler"}, params), ) return json_error(request)
def call_service(func, api_kwargs, context, request): """Wraps the request and the response, once a route does match.""" # apply validators for validator in api_kwargs.get('validators', []): validator(request) if len(request.errors) > 0: return json_error(request.errors) response = func(request) # We can't apply filters at this level, since "response" may not have # been rendered into a proper Response object yet. Instead, give the # request a reference to its api_kwargs so that a tween can apply them. request.cornice_api_kwargs = api_kwargs return response
def error_handler(errors): params = { 'ERROR_STATUS': errors.status } params['ROLE'] = str(errors.request.authenticated_role) if errors.request.params: params['PARAMS'] = str(dict(errors.request.params)) if errors.request.matchdict: for x, j in errors.request.matchdict.items(): params[x.upper()] = j if 'tender' in errors.request.validated: params['TENDER_REV'] = errors.request.validated['tender'].rev params['TENDERID'] = errors.request.validated['tender'].tenderID params['TENDER_STATUS'] = errors.request.validated['tender'].status LOGGER.info('Error on processing request "{}"'.format(dumps(errors, indent=4)), extra=context_unpack(errors.request, {'MESSAGE_ID': 'error_handler'}, params)) return json_error(errors)
def call_service(func, api_kwargs, context, request): """Wraps the request and the response, once a route does match.""" # apply validators for validator in api_kwargs.get("validators", []): validator(request) if len(request.errors) > 0: return json_error(request.errors) response = func(request) # We can't apply filters at this level, since "response" may not have # been rendered into a proper Response object yet. Instead, give the # request a reference to its api_kwargs so that a tween can apply them. request.cornice_api_kwargs = api_kwargs return response
def _put_data(self, replace=False): items = self.collection_serialize() if len(self.request.errors) > 0: return json_error(self.request.errors) if replace: # delete previous entries self.dbsession.query(self.mapping).delete() dbitems = [] for item in items: item = self.mapping(**item) self.dbsession.add(item) dbitems.append(item) self.dbsession.commit() return {'ids': [getattr(item, self.primary_key) for item in dbitems]}
def error_handler(errors): for i in LOGGER.handlers: if isinstance(i, JournalHandler): i._extra['ERROR_STATUS'] = errors.status if 'ROLE' not in i._extra: i._extra['ROLE'] = str(errors.request.authenticated_role) if errors.request.params and 'PARAMS' not in i._extra: i._extra['PARAMS'] = str(dict(errors.request.params)) if errors.request.matchdict: for x, j in errors.request.matchdict.items(): i._extra[x.upper()] = j if 'tender' in errors.request.validated: i._extra['TENDERID'] = errors.request.validated['tender'].tenderID i._extra['TENDER_STATUS'] = errors.request.validated['tender'].status LOGGER.info('Error on processing request "{}"'.format(dumps(errors, indent=4)), extra={'MESSAGE_ID': 'error_handler'}) for i in LOGGER.handlers: LOGGER.removeHandler(i) return json_error(errors)
def error_handler(errors, request_params=True): params = { 'ERROR_STATUS': errors.status } if request_params: params['ROLE'] = str(errors.request.authenticated_role) if errors.request.params: params['PARAMS'] = str(dict(errors.request.params)) if errors.request.matchdict: for x, j in errors.request.matchdict.items(): params[x.upper()] = j if 'auction' in errors.request.validated: params['AUCTION_REV'] = errors.request.validated['auction'].rev params['AUCTIONID'] = errors.request.validated['auction'].auctionID params['AUCTION_STATUS'] = errors.request.validated['auction'].status LOGGER.info('Error on processing request "{}"'.format(dumps(errors, indent=4)), extra=context_unpack(errors.request, {'MESSAGE_ID': 'error_handler'}, params)) return json_error(errors)
def wrapper(request): # if the args contain a klass argument then use it to resolve the view # location (if the view argument isn't a callable) ob = None view_ = view if 'klass' in args: ob = args['klass'](request) if isinstance(view, basestring): view_ = getattr(ob, view.lower()) # do schema validation if 'schema' in args: validate_colander_schema(args['schema'], request) # the validators can either be a list of callables or contain some # non-callable values. In which case we want to resolve them using the # object if any validators = args.get('validators', ()) for validator in validators: if isinstance(validator, basestring) and ob is not None: validator = getattr(ob, validator) validator(request) if len(request.errors) > 0: return json_error(request.errors) # if we have an object, the request had already been passed to it if ob: response = view_() else: response = view_(request) # We can't apply filters at this level, since "response" may not have # been rendered into a proper Response object yet. Instead, give the # request a reference to its api_kwargs so that a tween can apply them. # We also pass the object we created (if any) so we can use it to find # the filters that are in fact methods. request.cornice_args = (args, ob) return response
def http_error_handler(exc, request): """In case of a HTTP error, return the error details as JSON, e.g.: { "status": "error", "errors": [ { "location": "request", "name": "Not Found", "description": "document not found" } ] } """ if isinstance(exc, _JSONError): # if it is an error from Cornice, just return it return exc errors = Errors(request, exc.code) errors.add('request', exc.title, exc.detail) return json_error(errors)
def http_error_handler(exc, request): """In case of a HTTP error, return the error details as JSON, e.g.: { "status": "error", "errors": [ { "location": "body", "name": "Not Found", "description": "document not found" } ] } """ if isinstance(exc, _JSONError): # if it is an error from Cornice, just return it return exc request.errors = Errors(exc.code) request.errors.add('body', exc.title, exc.detail) return json_error(request)
def call_service(func, api_kwargs, context, request): wrap_request(request) # Checking that the accept headers sent by the client # match what can be handled by the function, if specified. # # If not, returns a HTTP 406 NOT ACCEPTABLE with the list of available # choices if 'accept' in request.headers and 'accept' in api_kwargs: accept = api_kwargs.get('accept') if callable(accept): acceptable = accept(request) else: acceptable = accept acceptable = to_list(acceptable) # does it comply with the headers sent by the client? best_match = request.accept.best_match(acceptable) if best_match: return func(request) else: # if not, return the list of accepted headers resp = request.response resp.status = 406 resp.content_type = "application/json" resp.body = json.dumps(acceptable) return resp for validator in to_list(api_kwargs.get('validator', [])): validator(request) if len(request.errors) > 0: return json_error(request.errors) return func(request)
def _validate_request(self, request, data): """Raise a cornice compatible error when the application is not one of the defined ones""" if self.applications == {}: return application = request.matchdict.get('application') version = request.matchdict.get('version') errors = Errors() if application not in self.applications: errors.add("uri", "application", "the application %r is not defined, please use one of %s" % ( application, ", ".join(self.applications.keys()))) if version not in self.applications[application]: versions = self.applications[application] errors.add("uri", "version", ("the application %r is not defined for this version, please " "use one of %s") % (application, ", ".join(versions))) if len(errors) > 0: raise json_error(errors, 404)
def get(self): self.request.errors.add("request", "method", "Method not allowed") self.request.errors.status = 405 raise json_error(self.request.errors)
def account_error_handler(exc, request): request.errors = Errors(400) request.errors.add('body', 'Error', exc.args) return json_error(request)
def account_error_handler(exc, request): errors = Errors(request, 400) errors.add('request', 'Error', exc.args) return json_error(errors)
else: if hasattr(type(m), '_options') and role not in type(m)._options.roles: request.errors.add('url', 'role', 'Forbidden') request.errors.status = 403 else: data = method(role) request.validated['data'] = data if not partial: m = model(data) m.__parent__ = request.context request.validated[model.__name__.lower()] = m return data # here just validation if request.json_body is json type. Return json without "data" prefix. # if there is error then return it with serialization def validate_json_data(request): try: json = request.json_body except ValueError, e: request.errors.add('body', 'data', e.message) request.errors.status = 422 raise json_error(request.errors) if not isinstance(json, dict) or 'data' not in json or not isinstance( json.get('data'), dict): request.errors.add('body', 'data', "Data not available") request.errors.status = 422 raise json_error(request.errors) request.validated['json_data'] = json['data'] return json['data']
def handle_error(response, location): request = get_current_request() response_dict = object_attributes_to_dict(response, ['url', 'status_code', 'reason', 'headers', 'content']) # Compute name name = 'http-response' body = response_dict['content'] if 'CLIENT.CQL' in body: name = 'expression' if 'SERVER.DomainAccess' in body or 'EpoqueCommand short-circuited and fallback disabled' in body: response_dict['content'] += \ "<br/><br/>" \ "The OPS API might be in maintenance mode, this happens regularly at 05:00 a.m. <br/>" \ "and usually does not last longer than 30 minutes." request.errors.add(location, name, response_dict) response_json = json_error(request) response_json.status = response.status_code # countermeasure against "_JSONError: <unprintable _JSONError object>" or the like response_json.detail = str(response.status_code) + ' ' + response.reason + ': ' + response.content #print "response:", response if len(request.errors) == 1: error_info = request.errors[0].get('description') if error_info.get('status_code') == 404: error_content = error_info.get('content', '') url = error_info.get('url') status = str(error_info.get('status_code', '')) + ' ' + error_info.get('reason', '') if 'CLIENT.InvalidCountryCode' in error_content: ops_code = 'CLIENT.InvalidCountryCode' message = u'OPS API response ({status}, {ops_code}). url={url}'.format(status=status, ops_code=ops_code, url=url) log.error(message) return response_json if 'SERVER.EntityNotFound' in error_content: ops_code = 'SERVER.EntityNotFound' message = u'OPS API response ({status}, {ops_code}). url={url}'.format(status=status, ops_code=ops_code, url=url) log.warning(message) return response_json if 'OPS - 404' in error_content or 'Page not found' in error_content: ops_code = '404 OPS Page not found' message = u'OPS API response ({status}, {ops_code}). url={url}'.format(status=status, ops_code=ops_code, url=url) log.error(message) log.error(u'OPS API errors:\n{}'.format(pformat(request.errors))) response_json.status_code = 502 return response_json if 'This API version is not supported' in error_content: ops_code = '404 API version not supported' message = u'OPS API response ({status}, {ops_code}). url={url}'.format(status=status, ops_code=ops_code, url=url) log.error(message) response_json.status_code = 502 return response_json log.error(u'OPS API errors:\n{}'.format(pformat(request.errors))) return response_json
def main_api(request): add_error(request, 'Route not found', 'There was no route given') return json_error(request)