def test_status_categories(self): self.assertFalse(is_informational(99)) self.assertTrue(is_informational(100)) self.assertTrue(is_informational(199)) self.assertFalse(is_informational(200)) self.assertFalse(is_success(199)) self.assertTrue(is_success(200)) self.assertTrue(is_success(299)) self.assertFalse(is_success(300)) self.assertFalse(is_redirect(299)) self.assertTrue(is_redirect(300)) self.assertTrue(is_redirect(399)) self.assertFalse(is_redirect(400)) self.assertFalse(is_client_error(399)) self.assertTrue(is_client_error(400)) self.assertTrue(is_client_error(499)) self.assertFalse(is_client_error(500)) self.assertFalse(is_server_error(499)) self.assertTrue(is_server_error(500)) self.assertTrue(is_server_error(599)) self.assertFalse(is_server_error(600))
def test_survey_smoke_test(self, data): client = Client() # First test with an unauthenticated user username = "******" email = "*****@*****.**" password = "******" User.objects.create_user(username, email, password) response = client.post(reverse("survey-list"), json.dumps(data), content_type="application/json") self.assertFalse(status.is_server_error(response.status_code), response.json()) # Now test with a logged in user login = client.login(username=username, password=password) self.assertTrue(login) response = client.post(reverse("survey-list"), json.dumps(data), content_type="application/json") self.assertFalse(status.is_server_error(response.status_code), response.json()) self.crawl("http://testserver" + reverse("api-root"), seen=[]) for s in Survey.objects.all(): assert s.get_absolute_url()
def test_survey_smoke_test(self, data): client = Client() # First test with an unauthenticated user username = '******' email = '*****@*****.**' password = '******' User.objects.create_user(username, email, password) response = client.post(reverse('survey-list'), json.dumps(data), content_type='application/json') self.assertFalse( status.is_server_error(response.status_code), response.json()) # Now test with a logged in user login = client.login(username=username, password=password) self.assertTrue(login) response = client.post(reverse('survey-list'), json.dumps(data), content_type='application/json') self.assertFalse( status.is_server_error(response.status_code), response.json()) self.crawl('http://testserver' + reverse('api-root'), seen=[], client=client) for s in Survey.objects.all(): assert isinstance(str(s), str) assert s.get_absolute_url()
def django_exception_handler(response): exc = sys.exc_info()[1] if any(map(lambda c: isinstance(exc, c), other_exceptions_map.keys())): status_code, message, developer_message, reason = (None, None, None, None) for other_exception, value in other_exceptions_map.items(): if isinstance(exc, other_exception): status_code, message, developer_message, reason = value break else: status_code = response.status_code if status.is_server_error(status_code): message = _("Server Error, try again later") reason = ERROR_REASON.INTERNAL_ERROR else: message = _("Bad request") reason = ERROR_REASON.BAD_REQUEST if exc: msg = str(exc).decode('utf') developer_message = "%s: %s" % (exc.__class__.__name__, msg) else: developer_message = getattr(response, 'reason_phrase', "Contact server admin with `request_id`") errors = [{'message': message, 'reason': reason}] data = exception_response_date(status_code, message, developer_message, errors) return exception_response(data, status_code, headers={}, django=True)
def finalize_response(self, request, response, *args, **kwargs): # regular finalize response response = super().finalize_response(request, response, *args, **kwargs) status_code = response.status_code cur_time = request.start_time.astimezone() log_kwargs = { 'remote_address': request.META['REMOTE_ADDR'], 'server_hostname': socket.gethostname(), 'method': request.method, 'status_code': status_code, 'request_params': request.query_params, 'access_time': request.start_time.astimezone().strftime("%Y-%m-%d %H:%M:%S"), 'service_time': (datetime.now(timezone.utc) - request.start_time).total_seconds(), 'service_provider': "NULL", 'data_source': "https://www.who.int/emergencies/diseases/news/en/" } if status.is_server_error(status_code): logger.error('error', extra=log_kwargs) elif status.is_client_error(status_code): logger.warning('warning', extra=log_kwargs) else: logger.info('info', extra=log_kwargs) response['log'] = log_kwargs return response
def exception_handler(exc, context): """ When error is raised inside API view, it will be processed by this function. :param exc: Exception to process. :return: Response with error JSON. """ response_data = {'error_code': 'internal'} status = HTTP_500_INTERNAL_SERVER_ERROR if isinstance(exc, BaseApiError): response_data.update(exc.format_exc()) status = exc.status_code if is_server_error(status): logger.critical('Internal API exception', exc_info=exc) if settings.DEBUG: raise logging.info( 'Error response. status_code=%s, error_code=%s', status, response_data['error_code'], ) return Response( DataWithStatus('error', **response_data), status=status, )
def get_comment(self, check_permissions=True): pk = self.kwargs[self.comment_lookup_url_kwarg] try: comment = Comment.find_one(Q('_id', 'eq', pk) & Q('root_target', 'ne', None)) except NoResultsFound: raise NotFound # Deleted root targets still appear as tuples in the database and are included in # the above query, requiring an additional check if isinstance(comment.root_target.referent, TrashedFileNode): comment.root_target = None comment.save() if comment.root_target is None: raise NotFound if isinstance(comment.root_target.referent, StoredFileNode): root_target = comment.root_target referent = root_target.referent if referent.provider == 'osfstorage': try: StoredFileNode.find( Q('node', 'eq', comment.node._id) & Q('_id', 'eq', referent._id) & Q('is_file', 'eq', True) ) except NoResultsFound: Comment.update(Q('root_target', 'eq', root_target), data={'root_target': None}) raise NotFound else: if referent.provider == 'dropbox': # referent.path is the absolute path for the db file, but wb requires the relative path referent = DropboxFile.load(referent._id) url = waterbutler_api_url_for(comment.node._id, referent.provider, referent.path, meta=True) waterbutler_request = requests.get( url, cookies=self.request.COOKIES, headers={'Authorization': self.request.META.get('HTTP_AUTHORIZATION')}, ) if waterbutler_request.status_code == 401: raise PermissionDenied if waterbutler_request.status_code == 404: Comment.update(Q('root_target', 'eq', root_target), data={'root_target': None}) raise NotFound if is_server_error(waterbutler_request.status_code): raise ServiceUnavailableError(detail='Could not retrieve files information at this time.') try: waterbutler_request.json()['data'] except KeyError: raise ServiceUnavailableError(detail='Could not retrieve files information at this time.') if check_permissions: # May raise a permission denied self.check_object_permissions(self.request, comment) return comment
def get_file_object(node, path, provider, request): if provider == 'osfstorage': # Kinda like /me for a user # The one odd case where path is not really path if path == '/': obj = node.get_addon('osfstorage').get_root() else: obj = get_object_or_error( OsfStorageFileNode, Q('node', 'eq', node._id) & Q('_id', 'eq', path.strip('/')) & Q('is_file', 'eq', not path.endswith('/')) ) return obj url = waterbutler_api_url_for(node._id, provider, path, meta=True) waterbutler_request = requests.get( url, cookies=request.COOKIES, headers={'Authorization': request.META.get('HTTP_AUTHORIZATION')}, ) if waterbutler_request.status_code == 401: raise PermissionDenied if waterbutler_request.status_code == 404: raise NotFound if is_server_error(waterbutler_request.status_code): raise ServiceUnavailableError(detail='Could not retrieve files information at this time.') try: return waterbutler_request.json()['data'] except KeyError: raise ServiceUnavailableError(detail='Could not retrieve files information at this time.')
def _sync_company_with_dnb( company_id, fields_to_update, task, update_descriptor, retry_failures=True, ): dh_company = Company.objects.get(id=company_id) try: dnb_company = get_company(dh_company.duns_number) except DNBServiceError as exc: if is_server_error(exc.status_code) and retry_failures: raise task.retry(exc=exc, countdown=60) raise except (DNBServiceConnectionError, DNBServiceTimeoutError) as exc: if retry_failures: raise task.retry(exc=exc, countdown=60) raise update_company_from_dnb( dh_company, dnb_company, fields_to_update=fields_to_update, update_descriptor=update_descriptor, )
def test_survey_response_smoke_test(self, survey_response): client = Client() username = "******" email = "*****@*****.**" password = "******" u = User.objects.create_user(username, email, password) login = client.login(username=username, password=password) self.assertTrue(login) response = client.post(reverse("response-list"), json.dumps(survey_response), content_type="application/json") self.assertFalse(status.is_server_error(response.status_code), response.json()) # Make a survey s = {"owner": u.id, "name": "a title", "schema": EXAMPLE_SCHEMA} response = client.post(reverse("survey-list"), json.dumps(s), content_type="application/json") self.assertTrue(status.is_success(response.status_code), response.content) # Upload the result again survey_response["survey"] = response.json()["id"] response = client.post(reverse("response-list"), json.dumps(survey_response), content_type="application/json") self.assertTrue(status.is_success(response.status_code), response.content) self.crawl("http://testserver" + reverse("api-root"), seen=[])
def render(self, data, accepted_media_type=None, renderer_context=None): """Convert native DRF data to JSON API RC1. The four expected kinds of data are: - No data (maybe in response to 204 No Content) - Error data (status code is 4xx or 5xx) - Standard data (with serializer and fields_extra) - Paginated data """ response = renderer_context.get('response') request = renderer_context.get('request') fields_extra = renderer_context.get('fields_extra') status_code = response and response.status_code is_err = is_client_error(status_code) or is_server_error(status_code) if data is None: converted = None elif is_err: converted = self.convert_error(data, status_code) elif all([key in data for key in self.PAGINATION_KEYS]): converted = self.convert_paginated(data, request) elif request and request.method == 'OPTIONS': converted = {'meta': data} else: main_resource = fields_extra['id']['resource'] converted = self.convert_standard(data, fields_extra, main_resource, request) renderer_context['indent'] = 4 return super(JsonApiRC1Renderer, self).render(data=converted, renderer_context=renderer_context)
def test_map_function_smoke_test(self, map_function_data): client = Client() username = '******' email = '*****@*****.**' password = '******' u = User.objects.create_user(username, email, password) login = client.login(username=username, password=password) self.assertTrue(login) # Make a survey s = { 'owner': u.id, 'name': 'a title', 'schema': EXAMPLE_SCHEMA } response = client.post(reverse('survey-list'), json.dumps(s), content_type='application/json') self.assertTrue( status.is_success(response.status_code), response.content) response = client.post(reverse('map_function-list'), json.dumps(map_function_data), content_type='application/json') self.assertFalse( status.is_server_error(response.status_code), response.content) self.crawl('http://testserver' + reverse('api-root'), seen=[], client=client)
def finalize_response(self, request, response, *args, **kwargs): """Override finalize_response""" # regular finalize response response = super().finalize_response(request, response, *args, **kwargs) # do not log, if method not found if request.method.lower() not in self.allowed_logging_methods: return response status_code = response.status_code log_kwargs = { 'view': self.get_view_name(), 'action': self.action, 'method': request.method.lower(), 'status_code': status_code, 'request_path': request.path, 'request_data': request.data, } if status.is_server_error(status_code): LOGGER.error('DRF server error: {}'.format( json.dumps(log_kwargs, cls=DjangoWithFileJSONEncoder))) elif status.is_client_error(status_code): LOGGER.warning('DRF client error: {}'.format( json.dumps(log_kwargs, cls=DjangoWithFileJSONEncoder))) else: LOGGER.info("DRF successfully finished: {}".format( json.dumps(log_kwargs, cls=DjangoWithFileJSONEncoder))) return response
def wrap_generic_error(self, data, renderer_context): """ Convert generic error native data using the JSON API Error format See the note about the JSON API Error format on `wrap_error`. The native format for errors that are not bad requests, such as authentication issues or missing content, is a dictionary with a 'detail' key and a string value: { "detail": "Authentication credentials were not provided." } This is rendered into this JSON API error format: { "errors": [{ "status": "403", "title": "Authentication credentials were not provided" }] } """ response = renderer_context.get("response", None) status_code = response and response.status_code is_error = ( status.is_client_error(status_code) or status.is_server_error(status_code) ) if not is_error: raise WrapperNotApplicable("Status code must be 4xx or 5xx.") return self.wrap_error( data, renderer_context, keys_are_fields=False, issue_is_title=True)
def _get_http_status_code(code): result = code if status.is_success(code) or status.is_client_error(code): result = status.HTTP_200_OK elif status.is_server_error(code): result = status.HTTP_500_INTERNAL_SERVER_ERROR return result
def assertResponseServerError(self, response, msg=None): status_code = response.status_code if msg is not None: message = msg.format(status_code=status_code) else: message = None self.assertTrue(status.is_server_error(status_code), message)
def render(self, data, accepted_media_type=None, renderer_context=None): """Convert DRF native data to the JSON API v1.0 format.""" # Construct absolute URI for override path or request path (default) response = renderer_context.get('response') self.request = renderer_context['request'] self.request_uri = self.request.build_absolute_uri() override_path = renderer_context.get('override_path') resource_uri = self.request.build_absolute_uri(override_path) fields_extra = renderer_context.get('fields_extra') status_code = response and response.status_code exception = response and getattr(response, 'exc', None) is_err = is_client_error(status_code) or is_server_error(status_code) as_relationship = renderer_context.get('as_relationship') if data is None: # Deleted items converted = None elif all([key in data for key in self.PAGINATION_KEYS]): # Paginated object converted = self.convert_paginated( data, fields_extra, request_uri=self.request_uri) elif is_err: converted = self.convert_error( data, exception, fields_extra, status_code) elif self.request.method == 'OPTIONS': converted = {'meta': data} elif as_relationship: relationship_name = as_relationship if as_relationship not in data: # Relationship to current resource in a historical viewset # For example, historicalbrowsers/5/relationships/browser # In this case, 'as_relationship' is the singular name # (browser), but the link ID is in 'object_id'. assert 'object_id' in data, ( 'Expecting "%s" or object_id in data keys %s.' % (as_relationship, list(data.keys()))) assert 'object_id' in fields_extra, ( 'Expecting "object_id" in fields_extra.') assert 'name' in fields_extra['object_id'], ( 'Expecting "name" in fields_extra["object_id"].') object_name = fields_extra['object_id']['name'] assert object_name == as_relationship, ( ('Expecting fields_extra["object_id"]["name"] == "%s",' ' got "%s".') % (as_relationship, object_name)) relationship_name = 'object_id' converted = self.convert_to_relationship_object( relationship_name, data[relationship_name], fields_extra[relationship_name], resource_uri=resource_uri) else: converted = self.convert_document( data, fields_extra, resource_uri=resource_uri, request_uri=self.request_uri) renderer_context['indent'] = 4 return super(JsonApiV10Renderer, self).render( data=converted, accepted_media_type=accepted_media_type, renderer_context=renderer_context)
def _get_company_updates_from_api(last_updated_after, next_page, task): try: return get_company_update_page(last_updated_after, next_page) except DNBServiceError as exc: if is_server_error(exc.status_code): raise task.retry(exc=exc, countdown=60) raise except (DNBServiceConnectionError, DNBServiceTimeoutError) as exc: raise task.retry(exc=exc, countdown=60)
def get_comment(self, check_permissions=True): pk = self.kwargs[self.comment_lookup_url_kwarg] try: comment = Comment.find_one(Q('_id', 'eq', pk) & Q('root_target', 'ne', None)) except NoResultsFound: raise NotFound # Deleted root targets still appear as tuples in the database and are included in # the above query, requiring an additional check if comment.root_target is None: raise NotFound if isinstance(comment.root_target, StoredFileNode): root_target = comment.root_target if root_target.provider == 'osfstorage': try: StoredFileNode.find( Q('node', 'eq', comment.node._id) & Q('_id', 'eq', root_target._id) & Q('is_file', 'eq', True) ) except NoResultsFound: Comment.update(Q('root_target', 'eq', root_target), data={'root_target': None}) del comment.node.commented_files[root_target._id] raise NotFound else: if root_target.provider == 'dropbox': root_target = DropboxFile.load(comment.root_target._id) url = waterbutler_api_url_for(comment.node._id, root_target.provider, root_target.path, meta=True) waterbutler_request = requests.get( url, cookies=self.request.COOKIES, headers={'Authorization': self.request.META.get('HTTP_AUTHORIZATION')}, ) if waterbutler_request.status_code == 401: raise PermissionDenied if waterbutler_request.status_code == 404: Comment.update(Q('root_target', 'eq', root_target), data={'root_target': None}) raise NotFound if is_server_error(waterbutler_request.status_code): raise ServiceUnavailableError(detail='Could not retrieve files information at this time.') try: waterbutler_request.json()['data'] except KeyError: raise ServiceUnavailableError(detail='Could not retrieve files information at this time.') if check_permissions: # May raise a permission denied self.check_object_permissions(self.request, comment) return comment
def get_file_object(target, path, provider, request): # Don't bother going to waterbutler for osfstorage if provider == 'osfstorage': # Kinda like /me for a user # The one odd case where path is not really path if path == '/': if isinstance(target, AbstractNode): obj = target.get_addon('osfstorage').get_root() elif isinstance(target, Preprint): obj = target.root_folder else: obj = target else: if path.endswith('/'): model = OsfStorageFolder else: model = OsfStorageFile content_type = ContentType.objects.get_for_model(target) obj = get_object_or_error(model, Q(target_object_id=target.pk, target_content_type=content_type, _id=path.strip('/')), request) return obj if isinstance(target, AbstractNode) and not target.get_addon(provider) or not target.get_addon(provider).configured: raise NotFound('The {} provider is not configured for this project.'.format(provider)) view_only = request.query_params.get('view_only', default=None) base_url = None if hasattr(target, 'osfstorage_region'): base_url = target.osfstorage_region.waterbutler_url url = waterbutler_api_url_for( target._id, provider, path, _internal=True, base_url=base_url, meta=True, view_only=view_only, ) waterbutler_request = requests.get( url, cookies=request.COOKIES, headers={'Authorization': request.META.get('HTTP_AUTHORIZATION')}, ) if waterbutler_request.status_code == 401: raise PermissionDenied if waterbutler_request.status_code == 404: raise NotFound if is_server_error(waterbutler_request.status_code): raise ServiceUnavailableError(detail='Could not retrieve files information at this time.') try: return waterbutler_request.json()['data'] except KeyError: raise ServiceUnavailableError(detail='Could not retrieve files information at this time.')
def get_file_object(node, path, provider, request): # Don't bother going to waterbutler for osfstorage if provider == 'osfstorage': # Kinda like /me for a user # The one odd case where path is not really path if path == '/': obj = node.get_addon('osfstorage').get_root() else: if path.endswith('/'): model = OsfStorageFolder else: model = OsfStorageFile obj = get_object_or_error(model, Q(node=node.pk, _id=path.strip('/')), request) return obj if not node.get_addon(provider) or not node.get_addon(provider).configured: raise NotFound( 'The {} provider is not configured for this project.'.format( provider)) view_only = request.query_params.get('view_only', default=None) url = waterbutler_api_url_for(node._id, provider, path, _internal=True, meta=True, view_only=view_only) waterbutler_request = requests.get( url, cookies=request.COOKIES, headers={'Authorization': request.META.get('HTTP_AUTHORIZATION')}, ) if waterbutler_request.status_code == 401: raise PermissionDenied if waterbutler_request.status_code == 404: raise NotFound if is_server_error(waterbutler_request.status_code): raise ServiceUnavailableError( detail='Could not retrieve files information at this time.') try: return waterbutler_request.json()['data'] except KeyError: raise ServiceUnavailableError( detail='Could not retrieve files information at this time.')
def check_response_for_error(self, response): if (status.is_success(response.status_code) and response.status_code == status.HTTP_201_CREATED): return True if (status.is_success(response.status_code)): self._set_error("Error with other status %s" % response) raise PromsRequestError("Error with code %s" % response.status_code) if (status.is_client_error(response.status_code)): self._set_error("Client Error %s" % response) raise PromsRequestError("Client Error with code %s" % response.status_code) elif (status.is_server_error(response.status_code)): self._set_error("Server error %s" % response) raise PromsRequestError("Server error with code %s" % response.status_code)
def render(self, data, accepted_media_type=None, renderer_context=None): ignore_keys = ['success', 'message', 'status_code'] status_code = renderer_context['response'].status_code if status_code == 204: renderer_context['response'].status_code = 200 if not data: data = {} data['success'] = status.is_success(status_code) data['message'] = 'Request processed successfully.' if not status.is_success(status_code): if status.is_client_error(status_code): data['message'] = data.get('detail', '') elif status.is_server_error(status_code): data['message'] = data.get( 'detail', "A server error has occurred. Please contact administrator for assistance." ) if data['message'] == '': for key in data.keys(): if key not in ignore_keys: if isinstance(data[key], list): if isinstance(data[key][0], dict): data['message'] = data[key][0][list( data[key][0].keys())[0]] if isinstance(data['message'], list): data['message'] = key + " : " + data[ 'message'][0] else: data['message'] = key + " : " + data[key][0] else: data['message'] = data[key] break result = dict() for key in data.keys(): if key in ignore_keys: result[key] = data[key] if isinstance(data['message'], (dict, list)): result['message'] = self.flatten_dictionary(result['message']) return super().render(data=result, accepted_media_type=accepted_media_type, renderer_context=renderer_context) return super().render(data=data, accepted_media_type=accepted_media_type, renderer_context=renderer_context)
def get_user_messages(self, user): token = _build_jwt(get_user_model().objects.get(pk=user.pk)) headers = {'Authorization': 'Bearer {}'.format(token)} url = '{}{}{}'.format( settings.EXOLEVER_HOST, settings.SERVICE_CONVERSATIONS_HOST, 'api/{}/messages/'.format(user.uuid), ) response = requests.get(url, headers=headers) is_client_error = status.is_client_error(response.status_code) is_server_error = status.is_server_error(response.status_code) if not is_server_error and not is_client_error: return response.json() else: return []
def get_user_opportunities(self, user): token = _build_jwt(get_user_model().objects.get(pk=user.pk)) headers = {'Authorization': 'Bearer {}'.format(token)} url = '{}{}{}'.format( settings.EXOLEVER_HOST, settings.SERVICE_EXO_OPPORTUNITIES_HOST, 'api/opportunity/?only_published_by_you=true', ) response = requests.get(url, headers=headers) is_client_error = status.is_client_error(response.status_code) is_server_error = status.is_server_error(response.status_code) if not is_server_error and not is_client_error: return response.json() else: return []
def to_json_response(response): status_code = response.status_code data = None if status.is_success(status_code): if hasattr(response, 'is_rendered') and not response.is_rendered: response.render() data = {'data': response.content} elif status.is_redirect(status_code): data = {'redirect': response.url} elif (status.is_client_error(status_code) or status.is_server_error(status_code)): data = {'errors': [{'status': status_code}]} return JsonResponse(data)
def response_modification(response): """ Modify API response format. """ if (status.is_client_error(response.status_code) or status.is_server_error(response.status_code)) and ( status.HTTP_400_BAD_REQUEST != response.status_code): return response # Modify the response data modified_data = {} modified_data["code"] = response.status_code modified_data["status"] = get_status(response.status_code) modified_data["data"] = response.data response.data = modified_data return response
def log(cls): try: client_error = status.is_client_error(cls.response.status_code) server_error = status.is_server_error(cls.response.status_code) # Debug log for client errors or server errors if client_error or server_error: cls.log_debug() # Activity log for users # if not client_error and not server_error and cls.get_user_id(): if cls.get_user_id() and hasattr(cls.view, 'cls'): _cls = getattr(cls.view, 'cls') if getattr(_cls, 'activity_log', True) and not getattr( cls.request, 'ignore_activity_log', False): cls.log_activity() except Exception as e: print(str(e)) return cls
def to_json_response(response): status_code = response.status_code data = None if status.is_success(status_code): if hasattr(response, 'is_rendered') and not response.is_rendered: response.render() data = {'data': response.content} elif status.is_redirect(status_code): data = {'redirect': response.url} elif (status.is_client_error(status_code) or status.is_server_error(status_code)): data = {'errors': [{ 'status': status_code }]} return JsonResponse(data)
def log_drf_exception(exc, data, status_code, context): # Ignore 404 errors if isinstance(exc, Http404): return drf_request = context['request'] django_request = drf_request._request if _hasattr(drf_request, '_full_data'): # Parsed and should have `raw_body` as it would be set by `ShoutitJsonParser` body = getattr(django_request, 'raw_body', None) else: body = django_request.body if hasattr(drf_request.auth, 'client'): # Authorized (AccessToken) DRF requests client = drf_request.auth.client.name elif hasattr(drf_request.auth, 'key'): # Authorized (Token) DRF requests client = 'Token' elif hasattr(drf_request, 'client'): # Requests to `access_token` endpoint client = drf_request.client.name else: client = None view_name = context['view'].__class__.__name__ view_action = getattr(context['view'], 'action', 'None') exc_name = exc.__class__.__name__ msg = "%s:%s:%s -> %s" % (drf_request.version, view_name, view_action, exc_name) extra = { 'request': django_request, 'request_body': body, 'response_data': data, 'tags': { 'api_client': client } } if status.is_server_error(status_code): error_logger.error(msg, extra=extra, exc_info=True) else: error_logger.debug(msg, extra=extra, exc_info=True)
def crawl(self, obj, seen=[], client=None): ''' Crawls the API for urls to assert that all GET requests do not error. ''' if not client: client = Client() if isinstance(obj, dict): {k: self.crawl(v, seen, client) for k, v in obj.items()} elif isinstance(obj, list): [self.crawl(elem, seen, client) for elem in obj] elif isinstance(obj, str): # Is this a url? if obj.startswith('http://') and (obj not in seen): seen.append(obj) response = client.get(obj) self.assertFalse( status.is_server_error(response.status_code), response.content) self.crawl(response.json(), seen)
def get_file_object(node, path, provider, request): # Don't bother going to waterbutler for osfstorage if provider == 'osfstorage': # Kinda like /me for a user # The one odd case where path is not really path if path == '/': obj = node.get_addon('osfstorage').get_root() else: if path.endswith('/'): model = OsfStorageFolder else: model = OsfStorageFile obj = get_object_or_error(model, Q(node=node.pk, _id=path.strip('/')), request) return obj if not node.get_addon(provider) or not node.get_addon(provider).configured: raise NotFound('The {} provider is not configured for this project.'.format(provider)) view_only = request.query_params.get('view_only', default=None) url = waterbutler_api_url_for(node._id, provider, path, _internal=True, meta=True, view_only=view_only) waterbutler_request = requests.get( url, cookies=request.COOKIES, headers={'Authorization': request.META.get('HTTP_AUTHORIZATION')}, ) if waterbutler_request.status_code == 401: raise PermissionDenied if waterbutler_request.status_code == 404: raise NotFound if is_server_error(waterbutler_request.status_code): raise ServiceUnavailableError(detail='Could not retrieve files information at this time.') try: return waterbutler_request.json()['data'] except KeyError: raise ServiceUnavailableError(detail='Could not retrieve files information at this time.')
def finalize_response(self, request, response, *args, **kwargs): # regular finalize response response = super().finalize_response(request, response, *args, **kwargs) # do not log, if method not found if request.method.lower() not in self.allowed_logging_methods: return response status_code = response.status_code # time_delta = now() - self.request.info['date'] # response_time_ms = time_delta.total_seconds() * 1000 # log_kwargs = { # 'view': self.get_view_name(), # 'action': self.action, # 'method': request.method.lower(), # 'status_code': status_code, # 'response_time_ms': round(response_time_ms, 2), # 'request_path': request.path, # } req_time = self.request.info['req_time'] if status.is_server_error(status_code): log_result = 'Fail: status_{0}'.format(status_code) log_message = res_log_message(request, log_result, req_time) logger.error(log_message) elif status.is_client_error(status_code): log_result = 'Fail: status_{0}'.format(status_code) log_message = res_log_message(request, log_result, req_time) logger.warning(log_message) elif status_code == 200 or status_code == 201: log_result = 'Success: status_{0}'.format(status_code) log_message = res_log_message(request, log_result, req_time) logger.info(log_message) else: log_result = 'Fail: status_{0}'.format(status_code) log_message = res_log_message(request, log_result, req_time) logger.info(log_message) return response
def test_survey_response_smoke_test(self, survey_response): client = Client() username = '******' email = '*****@*****.**' password = '******' u = User.objects.create_user(username, email, password) login = client.login(username=username, password=password) self.assertTrue(login) response = client.post(reverse('response-list'), json.dumps(survey_response), content_type='application/json') self.assertFalse(status.is_server_error(response.status_code), response.json()) # Make a survey s = {'owner': u.id, 'name': 'a title', 'schema': EXAMPLE_SCHEMA} response = client.post(reverse('survey-list'), json.dumps(s), content_type='application/json') self.assertTrue(status.is_success(response.status_code), response.content) # Upload the result again survey_response['survey'] = response.json()['id'] response = client.post(reverse('response-list'), json.dumps(survey_response), content_type='application/json') self.assertTrue(status.is_success(response.status_code), response.content) self.crawl('http://testserver' + reverse('api-root'), seen=[])
def render(self, data, accepted_media_type=None, renderer_context=None): if status.is_client_error(renderer_context['response'].status_code) or \ status.is_server_error(renderer_context['response'].status_code): if isinstance(data, dict) and 'detail' in data: response_data = { 'success': False, 'data': None, 'error': data['detail'] } elif isinstance(data, dict): response_data = {'success': False, 'data': None, 'error': data} else: response_data = { 'success': False, 'data': None, 'error': str(data) } else: response_data = {'success': True, 'data': data, 'error': None} return super(JsonResponseRenderer, self).render(response_data, accepted_media_type, renderer_context)
def render(self, data, accepted_media_type=None, renderer_context=None): """ Custom API response format for all APIs Example success: { "code": 200, "status": "OK", "data": { "key": "value" } } Example error: { "code": 404, "status": "NOT_FOUND", "errors": [ { "detail": "Not found." } ] } """ response = renderer_context["response"] # Modify the response into a cohesive response format modified_data = {} modified_data["code"] = response.status_code modified_data["status"] = get_status(response.status_code) if status.is_client_error( response.status_code) or status.is_server_error( response.status_code): modified_data["errors"] = data else: modified_data["data"] = data return super().render(modified_data, accepted_media_type, renderer_context)
def make_rest_call(method, url, headers, data=None): response = None try: if method == 'GET': response = requests.get(url, headers=headers) elif method == 'DELETE': response = requests.delete(url, headers=headers) elif method == 'POST': response = requests.post(url, data=data, headers=headers) except (ConnectionError, HTTPError, Timeout) as e: logger.error('REST %s Connection exception : %s', method, e) except: logger.error('Unexpected REST %s error: %s', method, sys.exc_info()[0]) if response is None or status.is_server_error(response.status_code): msg = '{0} {1}'.format('Service temporarily unavailable:', urlparse(url).netloc) raise ServiceUnavailable(detail=msg) elif status.is_client_error(response.status_code): raise BadRequest() elif status.is_redirect(response.status_code): logger.warn('Redirect %s for %s', response.status_code, url) return response
def process_exception(request, exception): exc = exception sentry = capture_exception(exc) request_id = getattr(local, 'request_id', None) method, uri = request.method, request.build_absolute_uri() logger.exception(f'process_exception [{request_id}] {method} {uri}', extra={ 'request': request, }) if IS_DJADMIN: return None if not isinstance(exc, exceptions.APIException): exc = exceptions.APIException(detail=str(exc)) status_code = exc.status_code is_server_error = status.is_server_error(status_code) resp = make_rest_response( dict( _cd=apr.APICodes.error.value, _msg=drf_const.get_code_status(code=status_code), _trace=trace_request(request, sentry=sentry), detail=is_server_error and drf_const.API_EXCEPTION or exc.detail, ), status_code) return resp