Hello community,

here is the log from the commit of package python-django-health-check for 
openSUSE:Factory checked in at 2020-02-20 14:59:02
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-django-health-check (Old)
 and      /work/SRC/openSUSE:Factory/.python-django-health-check.new.26092 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-django-health-check"

Thu Feb 20 14:59:02 2020 rev:3 rq:777589 version:3.12.1

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/python-django-health-check/python-django-health-check.changes
    2019-11-25 15:23:25.301288778 +0100
+++ 
/work/SRC/openSUSE:Factory/.python-django-health-check.new.26092/python-django-health-check.changes
 2020-02-20 14:59:11.446736661 +0100
@@ -1,0 +2,6 @@
+Thu Feb 20 08:20:25 UTC 2020 - Tomáš Chvátal <[email protected]>
+
+- Update to 3.12.1:
+  * Add health_check Django command (CLI) (#217, #234)
+
+-------------------------------------------------------------------

Old:
----
  django-health-check-3.11.1.tar.gz

New:
----
  django-health-check-3.12.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-django-health-check.spec ++++++
--- /var/tmp/diff_new_pack.3oEDtS/_old  2020-02-20 14:59:12.910739533 +0100
+++ /var/tmp/diff_new_pack.3oEDtS/_new  2020-02-20 14:59:12.934739580 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-django-health-check
 #
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -19,7 +19,7 @@
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 %define skip_python2 1
 Name:           python-django-health-check
-Version:        3.11.1
+Version:        3.12.1
 Release:        0
 Summary:        Run checks on services like databases, queue servers, celery 
processes, etc
 License:        MIT

++++++ django-health-check-3.11.1.tar.gz -> django-health-check-3.12.1.tar.gz 
++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-health-check-3.11.1/PKG-INFO 
new/django-health-check-3.12.1/PKG-INFO
--- old/django-health-check-3.11.1/PKG-INFO     2019-10-29 09:05:50.000000000 
+0100
+++ new/django-health-check-3.12.1/PKG-INFO     2020-01-14 16:54:28.000000000 
+0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: django-health-check
-Version: 3.11.1
+Version: 3.12.1
 Summary: Run checks on services like databases, queue servers, celery 
processes, etc.
 Home-page: https://github.com/KristianOellegaard/django-health-check
 Author: Kristian Ollegaard
@@ -274,6 +274,26 @@
                 url(r'^ht/$', views.HealthCheckCustomView.as_view(), 
name='health_check_custom'),
             ]
         
+        Django command
+        --------------
+        
+        You can run the Django command `health_check` to perform your health 
checks via the command line,
+        or periodically with a cron, as follow:
+        
+        .. code::
+        
+            django-admin health_check
+        
+        This should yield the following output:
+        
+        .. code::
+        
+            DatabaseHealthCheck      ... working
+            CustomHealthCheck        ... unavailable: Something went wrong!
+        
+        Similar to the http version, a critical error will case the command to 
quit with the exit code `1`.
+        
+        
         Other resources
         ---------------
         
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-health-check-3.11.1/README.rst 
new/django-health-check-3.12.1/README.rst
--- old/django-health-check-3.11.1/README.rst   2019-10-29 09:05:17.000000000 
+0100
+++ new/django-health-check-3.12.1/README.rst   2020-01-14 16:53:51.000000000 
+0100
@@ -266,6 +266,26 @@
         url(r'^ht/$', views.HealthCheckCustomView.as_view(), 
name='health_check_custom'),
     ]
 
+Django command
+--------------
+
+You can run the Django command `health_check` to perform your health checks 
via the command line,
+or periodically with a cron, as follow:
+
+.. code::
+
+    django-admin health_check
+
+This should yield the following output:
+
+.. code::
+
+    DatabaseHealthCheck      ... working
+    CustomHealthCheck        ... unavailable: Something went wrong!
+
+Similar to the http version, a critical error will case the command to quit 
with the exit code `1`.
+
+
 Other resources
 ---------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-health-check-3.11.1/django_health_check.egg-info/PKG-INFO 
new/django-health-check-3.12.1/django_health_check.egg-info/PKG-INFO
--- old/django-health-check-3.11.1/django_health_check.egg-info/PKG-INFO        
2019-10-29 09:05:50.000000000 +0100
+++ new/django-health-check-3.12.1/django_health_check.egg-info/PKG-INFO        
2020-01-14 16:54:28.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: django-health-check
-Version: 3.11.1
+Version: 3.12.1
 Summary: Run checks on services like databases, queue servers, celery 
processes, etc.
 Home-page: https://github.com/KristianOellegaard/django-health-check
 Author: Kristian Ollegaard
@@ -274,6 +274,26 @@
                 url(r'^ht/$', views.HealthCheckCustomView.as_view(), 
name='health_check_custom'),
             ]
         
+        Django command
+        --------------
+        
+        You can run the Django command `health_check` to perform your health 
checks via the command line,
+        or periodically with a cron, as follow:
+        
+        .. code::
+        
+            django-admin health_check
+        
+        This should yield the following output:
+        
+        .. code::
+        
+            DatabaseHealthCheck      ... working
+            CustomHealthCheck        ... unavailable: Something went wrong!
+        
+        Similar to the http version, a critical error will case the command to 
quit with the exit code `1`.
+        
+        
         Other resources
         ---------------
         
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-health-check-3.11.1/django_health_check.egg-info/SOURCES.txt 
new/django-health-check-3.12.1/django_health_check.egg-info/SOURCES.txt
--- old/django-health-check-3.11.1/django_health_check.egg-info/SOURCES.txt     
2019-10-29 09:05:50.000000000 +0100
+++ new/django-health-check-3.12.1/django_health_check.egg-info/SOURCES.txt     
2020-01-14 16:54:28.000000000 +0100
@@ -24,6 +24,7 @@
 health_check/backends.py
 health_check/conf.py
 health_check/exceptions.py
+health_check/mixins.py
 health_check/plugins.py
 health_check/urls.py
 health_check/views.py
@@ -56,6 +57,9 @@
 health_check/db/models.py
 health_check/db/migrations/0001_initial.py
 health_check/db/migrations/__init__.py
+health_check/management/__init__.py
+health_check/management/commands/__init__.py
+health_check/management/commands/health_check.py
 health_check/storage/__init__.py
 health_check/storage/apps.py
 health_check/storage/backends.py
@@ -64,7 +68,9 @@
 tests/test_autodiscover.py
 tests/test_backends.py
 tests/test_cache.py
+tests/test_commands.py
 tests/test_db.py
+tests/test_mixins.py
 tests/test_plugins.py
 tests/test_rabbitmq.py
 tests/test_redis.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-health-check-3.11.1/health_check/management/commands/health_check.py 
new/django-health-check-3.12.1/health_check/management/commands/health_check.py
--- 
old/django-health-check-3.11.1/health_check/management/commands/health_check.py 
    1970-01-01 01:00:00.000000000 +0100
+++ 
new/django-health-check-3.12.1/health_check/management/commands/health_check.py 
    2020-01-14 16:53:51.000000000 +0100
@@ -0,0 +1,25 @@
+import sys
+
+from django.core.management.base import BaseCommand
+
+from health_check.mixins import CheckMixin
+
+
+class Command(CheckMixin, BaseCommand):
+    help = "Run health checks and exit 0 if everything went well."
+
+    def handle(self, *args, **options):
+        # perform all checks
+        errors = self.errors
+
+        for plugin in self.plugins:
+            style_func = self.style.SUCCESS if not plugin.errors else 
self.style.ERROR
+            self.stdout.write(
+                "{:<24} ... {}\n".format(
+                    plugin.identifier(),
+                    style_func(plugin.pretty_status())
+                )
+            )
+
+        if errors:
+            sys.exit(1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-health-check-3.11.1/health_check/mixins.py 
new/django-health-check-3.12.1/health_check/mixins.py
--- old/django-health-check-3.11.1/health_check/mixins.py       1970-01-01 
01:00:00.000000000 +0100
+++ new/django-health-check-3.12.1/health_check/mixins.py       2020-01-14 
16:53:51.000000000 +0100
@@ -0,0 +1,51 @@
+import copy
+
+from concurrent.futures import ThreadPoolExecutor
+
+from health_check.conf import HEALTH_CHECK
+from health_check.exceptions import ServiceWarning
+from health_check.plugins import plugin_dir
+
+
+class CheckMixin:
+    _errors = None
+    _plugins = None
+
+    @property
+    def errors(self):
+        if not self._errors:
+            self._errors = self.run_check()
+        return self._errors
+
+    @property
+    def plugins(self):
+        if not self._plugins:
+            self._plugins = sorted((
+                plugin_class(**copy.deepcopy(options))
+                for plugin_class, options in plugin_dir._registry
+            ), key=lambda plugin: plugin.identifier())
+        return self._plugins
+
+    def run_check(self):
+        errors = []
+
+        def _run(plugin):
+            plugin.run_check()
+            try:
+                return plugin
+            finally:
+                from django.db import connection
+                connection.close()
+
+        with ThreadPoolExecutor(max_workers=len(self.plugins) or 1) as 
executor:
+            for plugin in executor.map(_run, self.plugins):
+                if plugin.critical_service:
+                    if not HEALTH_CHECK['WARNINGS_AS_ERRORS']:
+                        errors.extend(
+                            e for e in plugin.errors
+                            if not isinstance(e, ServiceWarning)
+                        )
+                    else:
+                        errors.extend(plugin.errors)
+
+        return errors
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/django-health-check-3.11.1/health_check/storage/backends.py 
new/django-health-check-3.12.1/health_check/storage/backends.py
--- old/django-health-check-3.11.1/health_check/storage/backends.py     
2019-10-29 09:05:17.000000000 +0100
+++ new/django-health-check-3.12.1/health_check/storage/backends.py     
2020-01-14 16:53:51.000000000 +0100
@@ -65,8 +65,8 @@
             file_name = self.check_save(file_name, file_content)
             self.check_delete(file_name)
             return True
-        except Exception:
-            raise ServiceUnavailable('Unknown exception')
+        except Exception as e:
+            raise ServiceUnavailable('Unknown exception') from e
 
 
 class DefaultFileStorageHealthCheck(StorageHealthCheck):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-health-check-3.11.1/health_check/views.py 
new/django-health-check-3.12.1/health_check/views.py
--- old/django-health-check-3.11.1/health_check/views.py        2019-10-29 
09:05:17.000000000 +0100
+++ new/django-health-check-3.12.1/health_check/views.py        2020-01-14 
16:53:51.000000000 +0100
@@ -1,14 +1,10 @@
-import copy
 import re
-from concurrent.futures import ThreadPoolExecutor
 
 from django.http import HttpResponse, JsonResponse
 from django.views.decorators.cache import never_cache
 from django.views.generic import TemplateView
 
-from health_check.conf import HEALTH_CHECK
-from health_check.exceptions import ServiceWarning
-from health_check.plugins import plugin_dir
+from health_check.mixins import CheckMixin
 
 
 class MediaType:
@@ -81,51 +77,25 @@
         return self.weight.__lt__(other.weight)
 
 
-class MainView(TemplateView):
+class MainView(CheckMixin, TemplateView):
     template_name = 'health_check/index.html'
 
     @never_cache
     def get(self, request, *args, **kwargs):
-        errors = []
-
-        plugins = sorted((
-            plugin_class(**copy.deepcopy(options))
-            for plugin_class, options in plugin_dir._registry
-        ), key=lambda plugin: plugin.identifier())
-
-        def _run(plugin):
-            plugin.run_check()
-            try:
-                return plugin
-            finally:
-                from django.db import connection
-                connection.close()
-
-        with ThreadPoolExecutor(max_workers=len(plugins) or 1) as executor:
-            for plugin in executor.map(_run, plugins):
-                if plugin.critical_service:
-                    if not HEALTH_CHECK['WARNINGS_AS_ERRORS']:
-                        errors.extend(
-                            e for e in plugin.errors
-                            if not isinstance(e, ServiceWarning)
-                        )
-                    else:
-                        errors.extend(plugin.errors)
-
-        status_code = 500 if errors else 200
+        status_code = 500 if self.errors else 200
 
         format_override = request.GET.get('format')
 
         if format_override == 'json':
-            return self.render_to_response_json(plugins, status_code)
+            return self.render_to_response_json(self.plugins, status_code)
 
         accept_header = request.META.get('HTTP_ACCEPT', '*/*')
-        context = {'plugins': plugins, 'status_code': status_code}
         for media in MediaType.parse_header(accept_header):
             if media.mime_type in ('text/html', 'application/xhtml+xml', 
'text/*', '*/*'):
+                context = {'plugins': self.plugins, 'status_code': status_code}
                 return self.render_to_response(context, status=status_code)
             elif media.mime_type in ('application/json', 'application/*'):
-                return self.render_to_response_json(plugins, status_code)
+                return self.render_to_response_json(self.plugins, status_code)
         return HttpResponse(
             'Not Acceptable: Supported content types: text/html, 
application/json',
             status=406,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-health-check-3.11.1/tests/test_commands.py 
new/django-health-check-3.12.1/tests/test_commands.py
--- old/django-health-check-3.11.1/tests/test_commands.py       1970-01-01 
01:00:00.000000000 +0100
+++ new/django-health-check-3.12.1/tests/test_commands.py       2020-01-14 
16:53:51.000000000 +0100
@@ -0,0 +1,38 @@
+from io import StringIO
+
+import pytest
+
+from health_check.backends import BaseHealthCheckBackend
+from health_check.plugins import plugin_dir
+
+from django.core.management import call_command
+
+
+class FailPlugin(BaseHealthCheckBackend):
+    def check_status(self):
+        self.add_error('Oops')
+
+
+class OkPlugin(BaseHealthCheckBackend):
+    def check_status(self):
+        pass
+
+
+class TestCommand:
+    @pytest.yield_fixture(autouse=True)
+    def setup(self):
+        plugin_dir.reset()
+        plugin_dir.register(FailPlugin)
+        plugin_dir.register(OkPlugin)
+        yield
+        plugin_dir.reset()
+
+    def test_command(self):
+        stdout = StringIO()
+        with pytest.raises(SystemExit):
+            call_command("health_check", stdout=stdout)
+        stdout.seek(0)
+        assert stdout.read() == (
+            "FailPlugin               ... unknown error: Oops\n"
+            "OkPlugin                 ... working\n"
+        )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/django-health-check-3.11.1/tests/test_mixins.py 
new/django-health-check-3.12.1/tests/test_mixins.py
--- old/django-health-check-3.11.1/tests/test_mixins.py 1970-01-01 
01:00:00.000000000 +0100
+++ new/django-health-check-3.12.1/tests/test_mixins.py 2020-01-14 
16:53:51.000000000 +0100
@@ -0,0 +1,38 @@
+import pytest
+
+from health_check.backends import BaseHealthCheckBackend
+from health_check.mixins import CheckMixin
+from health_check.plugins import plugin_dir
+
+
+class FailPlugin(BaseHealthCheckBackend):
+    def check_status(self):
+        self.add_error('Oops')
+
+
+class OkPlugin(BaseHealthCheckBackend):
+    def check_status(self):
+        pass
+
+
+class Checker(CheckMixin):
+    pass
+
+
+class TestCheckMixin:
+    @pytest.yield_fixture(autouse=True)
+    def setup(self):
+        plugin_dir.reset()
+        plugin_dir.register(FailPlugin)
+        plugin_dir.register(OkPlugin)
+        yield
+        plugin_dir.reset()
+
+    def test_plugins(self):
+        assert len(Checker().plugins) == 2
+
+    def test_errors(self):
+        assert len(Checker().errors) == 1
+
+    def test_run_check(self):
+        assert len(Checker().run_check()) == 1


Reply via email to