import six from django.conf import settings from django.http import HttpResponse, JsonResponse from django.http.response import Http404 from django.views.decorators.cache import cache_control from django.views.generic import View from django_healthchecks.checker import create_report, create_service_result from django_healthchecks.checker import PermissionDenied class NoCacheMixin(object): @classmethod def as_view(cls, **kwargs): view = super(NoCacheMixin, cls).as_view(**kwargs) return cache_control( private=True, no_cache=True, no_store=True, max_age=0)(view) class HealthCheckView(NoCacheMixin, View): def get(self, request, *args, **kwargs): try: report, is_healthy = create_report(request=request) except PermissionDenied: response = HttpResponse(status=401) response['WWW-Authenticate'] = 'Basic realm="Healthchecks"' return response status_code = 200 if is_healthy else _get_err_status_code() return JsonResponse(report, status=status_code) class HealthCheckServiceView(NoCacheMixin, View): def get(self, request, service, *args, **kwargs): service_path = list(filter(lambda s: s, service.split('/'))) service = service_path.pop(0) try: result = create_service_result(service=service, request=request) except PermissionDenied: response = HttpResponse(status=401) response['WWW-Authenticate'] = 'Basic realm="Healthchecks"' return response return self.create_result_response(service, result, service_path) def create_result_response(self, service, result, service_path): for nested in service_path: result = result.get(nested, None) if result is None: break if result is None: raise Http404() if result in (True, False): status_code = 200 if result else _get_err_status_code() return HttpResponse(str(result).lower(), status=status_code) elif isinstance(result, six.string_types) or isinstance(result, bytes): return HttpResponse(result) else: # Django requires safe=False for non-dict values. return JsonResponse(result, safe=False) def _get_err_status_code(): return getattr(settings, 'HEALTH_CHECKS_ERROR_CODE', 200)