django-health-check 3.23.3__py3-none-any.whl → 4.0rc2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. {django_health_check-3.23.3.dist-info → django_health_check-4.0rc2.dist-info}/METADATA +9 -5
  2. django_health_check-4.0rc2.dist-info/RECORD +20 -0
  3. health_check/__init__.py +5 -14
  4. health_check/_version.py +3 -3
  5. health_check/base.py +93 -0
  6. health_check/checks.py +329 -0
  7. health_check/contrib/celery.py +70 -0
  8. health_check/contrib/kafka.py +69 -0
  9. health_check/contrib/rabbitmq.py +43 -0
  10. health_check/contrib/redis.py +63 -0
  11. health_check/contrib/rss.py +113 -0
  12. health_check/exceptions.py +5 -13
  13. health_check/management/commands/health_check.py +20 -66
  14. health_check/templates/health_check/index.html +61 -43
  15. health_check/views.py +176 -75
  16. django_health_check-3.23.3.dist-info/RECORD +0 -63
  17. health_check/backends.py +0 -101
  18. health_check/cache/__init__.py +0 -0
  19. health_check/cache/apps.py +0 -14
  20. health_check/cache/backends.py +0 -50
  21. health_check/conf.py +0 -8
  22. health_check/contrib/celery/__init__.py +0 -3
  23. health_check/contrib/celery/apps.py +0 -31
  24. health_check/contrib/celery/backends.py +0 -46
  25. health_check/contrib/celery/tasks.py +0 -6
  26. health_check/contrib/celery_ping/__init__.py +0 -0
  27. health_check/contrib/celery_ping/apps.py +0 -19
  28. health_check/contrib/celery_ping/backends.py +0 -74
  29. health_check/contrib/db_heartbeat/__init__.py +0 -0
  30. health_check/contrib/db_heartbeat/apps.py +0 -19
  31. health_check/contrib/db_heartbeat/backends.py +0 -44
  32. health_check/contrib/mail/__init__.py +0 -0
  33. health_check/contrib/mail/apps.py +0 -19
  34. health_check/contrib/mail/backends.py +0 -61
  35. health_check/contrib/migrations/__init__.py +0 -0
  36. health_check/contrib/migrations/apps.py +0 -19
  37. health_check/contrib/migrations/backends.py +0 -31
  38. health_check/contrib/psutil/__init__.py +0 -0
  39. health_check/contrib/psutil/apps.py +0 -36
  40. health_check/contrib/psutil/backends.py +0 -63
  41. health_check/contrib/rabbitmq/__init__.py +0 -3
  42. health_check/contrib/rabbitmq/apps.py +0 -19
  43. health_check/contrib/rabbitmq/backends.py +0 -57
  44. health_check/contrib/redis/__init__.py +0 -3
  45. health_check/contrib/redis/apps.py +0 -19
  46. health_check/contrib/redis/backends.py +0 -75
  47. health_check/contrib/s3boto3_storage/__init__.py +0 -0
  48. health_check/contrib/s3boto3_storage/apps.py +0 -19
  49. health_check/contrib/s3boto3_storage/backends.py +0 -32
  50. health_check/contrib/s3boto_storage/__init__.py +0 -0
  51. health_check/contrib/s3boto_storage/apps.py +0 -20
  52. health_check/contrib/s3boto_storage/backends.py +0 -27
  53. health_check/db/__init__.py +0 -0
  54. health_check/db/apps.py +0 -20
  55. health_check/db/backends.py +0 -23
  56. health_check/db/migrations/0001_initial.py +0 -34
  57. health_check/db/migrations/0002_alter_testmodel_options.py +0 -32
  58. health_check/db/migrations/__init__.py +0 -0
  59. health_check/db/models.py +0 -9
  60. health_check/deprecation.py +0 -35
  61. health_check/mixins.py +0 -86
  62. health_check/plugins.py +0 -25
  63. health_check/storage/__init__.py +0 -0
  64. health_check/storage/apps.py +0 -12
  65. health_check/storage/backends.py +0 -73
  66. health_check/urls.py +0 -18
  67. {django_health_check-3.23.3.dist-info → django_health_check-4.0rc2.dist-info}/WHEEL +0 -0
  68. {django_health_check-3.23.3.dist-info → django_health_check-4.0rc2.dist-info}/licenses/LICENSE +0 -0
@@ -1,27 +0,0 @@
1
- import logging
2
-
3
- from health_check.deprecation import deprecated
4
- from health_check.storage.backends import StorageHealthCheck
5
-
6
-
7
- @deprecated(
8
- "`S3BotoStorageHealthCheck` is deprecated: use `health_check.Storage` instead. Action: remove legacy storage checks and add `health_check.Storage` to your `HealthCheckView.checks`. See migration guide: https://codingjoe.dev/django-health-check/migrate-to-v4/ (docs/migrate-to-v4.md)."
9
- )
10
- class S3BotoStorageHealthCheck(StorageHealthCheck):
11
- """
12
- Tests the status of a `S3BotoStorage` file storage backend.
13
-
14
- S3BotoStorage is included in the `django-storages` package
15
- and recommended by for example Amazon and Heroku for Django
16
- static and media file storage on cloud platforms.
17
-
18
- ``django-storages`` can be found at https://git.io/v1lGx
19
- ``S3BotoStorage`` can be found at https://git.io/v1lGF
20
- """
21
-
22
- logger = logging.getLogger(__name__)
23
- storage = "storages.backends.s3boto.S3BotoStorage"
24
-
25
- def check_delete(self, file_name):
26
- storage = self.get_storage()
27
- storage.delete(file_name)
File without changes
health_check/db/apps.py DELETED
@@ -1,20 +0,0 @@
1
- import warnings
2
-
3
- from django.apps import AppConfig
4
-
5
- from health_check.plugins import plugin_dir
6
-
7
-
8
- class HealthCheckConfig(AppConfig):
9
- default_auto_field = "django.db.models.AutoField"
10
- name = "health_check.db"
11
-
12
- def ready(self):
13
- from .backends import DatabaseBackend
14
-
15
- warnings.warn(
16
- "The `health_check.db` app is deprecated: it is superseded by view-based checks. Action: remove `health_check.db` from `INSTALLED_APPS` and use `HealthCheckView` with an explicit `checks` list. See migration guide: https://codingjoe.dev/django-health-check/migrate-to-v4/ (docs/migrate-to-v4.md).",
17
- DeprecationWarning,
18
- )
19
-
20
- plugin_dir.register(DatabaseBackend)
@@ -1,23 +0,0 @@
1
- from django.db import DatabaseError, IntegrityError
2
-
3
- from health_check.backends import HealthCheck
4
- from health_check.deprecation import deprecated
5
- from health_check.exceptions import ServiceReturnedUnexpectedResult, ServiceUnavailable
6
-
7
- from .models import TestModel
8
-
9
-
10
- @deprecated(
11
- "`DatabaseBackend` is deprecated: use `health_check.Database` (new view-based Database check) instead. Action: remove legacy DatabaseBackend subclasses and configure `HealthCheckView` with `health_check.Database` in your `checks` list. See migration guide: https://codingjoe.dev/django-health-check/migrate-to-v4/ (docs/migrate-to-v4.md)."
12
- )
13
- class DatabaseBackend(HealthCheck):
14
- def check_status(self):
15
- try:
16
- obj = TestModel.objects.create(title="test")
17
- obj.title = "newtest"
18
- obj.save()
19
- obj.delete()
20
- except IntegrityError:
21
- raise ServiceReturnedUnexpectedResult("Integrity Error")
22
- except DatabaseError:
23
- raise ServiceUnavailable("Database error")
@@ -1,34 +0,0 @@
1
- # Generated by Django 1.10.1 on 2016-09-26 18:46
2
-
3
- from django.db import migrations, models
4
-
5
-
6
- class Migration(migrations.Migration):
7
- initial = True
8
-
9
- replaces = [
10
- ("health_check_db", "0001_initial"),
11
- ]
12
-
13
- dependencies = []
14
-
15
- operations = [
16
- migrations.CreateModel(
17
- name="TestModel",
18
- fields=[
19
- (
20
- "id",
21
- models.AutoField(
22
- auto_created=True,
23
- primary_key=True,
24
- serialize=False,
25
- verbose_name="ID",
26
- ),
27
- ),
28
- ("title", models.CharField(max_length=128)),
29
- ],
30
- options={
31
- "db_table": "health_check_db_testmodel",
32
- },
33
- ),
34
- ]
@@ -1,32 +0,0 @@
1
- # Generated by Django 4.2.20 on 2025-03-20 11:10
2
-
3
- from django.db import migrations
4
-
5
-
6
- def remove_test_model_default_permissions(apps, schema_editor):
7
- ContentType = apps.get_model("contenttypes", "ContentType")
8
- Permission = apps.get_model("auth", "Permission")
9
- db_alias = schema_editor.connection.alias
10
-
11
- try:
12
- test_model_content_type = ContentType.objects.using(db_alias).get(app_label="db", model="testmodel")
13
- Permission.objects.using(db_alias).filter(content_type=test_model_content_type).delete()
14
- except ContentType.DoesNotExist:
15
- return
16
-
17
-
18
- class Migration(migrations.Migration):
19
- dependencies = [
20
- ("db", "0001_initial"),
21
- ]
22
-
23
- operations = [
24
- migrations.AlterModelOptions(
25
- name="testmodel",
26
- options={"default_permissions": ()},
27
- ),
28
- migrations.RunPython(
29
- code=remove_test_model_default_permissions,
30
- reverse_code=migrations.RunPython.noop,
31
- ),
32
- ]
File without changes
health_check/db/models.py DELETED
@@ -1,9 +0,0 @@
1
- from django.db import models
2
-
3
-
4
- class TestModel(models.Model):
5
- title = models.CharField(max_length=128)
6
-
7
- class Meta:
8
- db_table = "health_check_db_testmodel"
9
- default_permissions = ()
@@ -1,35 +0,0 @@
1
- from __future__ import annotations
2
-
3
- try:
4
- from warnings import deprecated
5
- except ImportError:
6
- import functools
7
- import warnings
8
-
9
- def deprecated(message: str, *, category: type[Warning] | None = DeprecationWarning, stacklevel: int = 1):
10
- def _decorator(obj):
11
- obj.__deprecated__ = message
12
-
13
- # For classes, wrap __init__ to warn on instantiation
14
- if isinstance(obj, type):
15
- original_init = obj.__init__
16
-
17
- @functools.wraps(original_init)
18
- def new_init(self, *args, **kwargs):
19
- warnings.warn(message, category, stacklevel=stacklevel + 1)
20
- original_init(self, *args, **kwargs)
21
-
22
- obj.__init__ = new_init
23
- # For functions, wrap the function to warn on call
24
- else:
25
-
26
- @functools.wraps(obj)
27
- def wrapper(*args, **kwargs):
28
- warnings.warn(message, category, stacklevel=stacklevel + 1)
29
- return obj(*args, **kwargs)
30
-
31
- return wrapper
32
-
33
- return obj
34
-
35
- return _decorator
health_check/mixins.py DELETED
@@ -1,86 +0,0 @@
1
- import copy
2
- from collections import OrderedDict
3
- from concurrent.futures import ThreadPoolExecutor
4
-
5
- from django.db import connections
6
- from django.http import Http404
7
-
8
- from health_check.conf import HEALTH_CHECK
9
- from health_check.exceptions import HealthCheckException, ServiceWarning
10
- from health_check.plugins import plugin_dir
11
-
12
-
13
- class CheckMixin:
14
- _errors: list[HealthCheckException] | None = None
15
- _plugins = None
16
- use_threading: bool = not HEALTH_CHECK["DISABLE_THREADING"]
17
- warnings_as_errors: bool = HEALTH_CHECK["WARNINGS_AS_ERRORS"]
18
-
19
- @property
20
- def errors(self):
21
- if not self._errors:
22
- self._errors = self.run_check()
23
- return self._errors
24
-
25
- def check(self, subset=None):
26
- return self.run_check(subset=subset)
27
-
28
- @property
29
- def plugins(self):
30
- if not plugin_dir._registry:
31
- return OrderedDict({})
32
-
33
- if not self._plugins:
34
- registering_plugins = (
35
- plugin_class(**copy.deepcopy(options)) for plugin_class, options in plugin_dir._registry
36
- )
37
- registering_plugins = sorted(registering_plugins, key=repr)
38
- self._plugins = OrderedDict({repr(plugin): plugin for plugin in registering_plugins})
39
- return self._plugins
40
-
41
- def filter_plugins(self, subset=None):
42
- if subset is None:
43
- return self.plugins
44
-
45
- health_check_subsets = HEALTH_CHECK["SUBSETS"]
46
- if subset not in health_check_subsets or not self.plugins:
47
- raise Http404(f"Subset: '{subset}' does not exist.")
48
-
49
- selected_subset = set(health_check_subsets[subset])
50
- return {
51
- plugin_identifier: v
52
- for plugin_identifier, v in self.plugins.items()
53
- if plugin_identifier in selected_subset
54
- }
55
-
56
- def run_check(self, subset=None):
57
- errors = []
58
-
59
- def _run(plugin):
60
- plugin.run_check()
61
- try:
62
- return plugin
63
- finally:
64
- if self.use_threading:
65
- # DB connections are thread-local so we need to close them here
66
- connections.close_all()
67
-
68
- def _collect_errors(plugin):
69
- if plugin.critical_service:
70
- if not self.warnings_as_errors:
71
- errors.extend(e for e in plugin.errors if not isinstance(e, ServiceWarning))
72
- else:
73
- errors.extend(plugin.errors)
74
-
75
- plugins = dict(self.filter_plugins(subset=subset))
76
- plugin_instances = plugins.values()
77
-
78
- if not self.use_threading:
79
- for plugin in plugin_instances:
80
- _run(plugin)
81
- _collect_errors(plugin)
82
- else:
83
- with ThreadPoolExecutor(max_workers=len(plugin_instances) or 1) as executor:
84
- for plugin in executor.map(_run, plugin_instances):
85
- _collect_errors(plugin)
86
- return errors
health_check/plugins.py DELETED
@@ -1,25 +0,0 @@
1
- class AlreadyRegistered(Exception):
2
- pass
3
-
4
-
5
- class NotRegistered(Exception):
6
- pass
7
-
8
-
9
- class HealthCheckPluginDirectory:
10
- """Django health check registry."""
11
-
12
- def __init__(self):
13
- self._registry = [] # plugin_class class -> plugin options
14
-
15
- def reset(self):
16
- """Reset registry state, e.g. for testing purposes."""
17
- self._registry = []
18
-
19
- def register(self, plugin, **options):
20
- """Add the given plugin from the registry."""
21
- # Instantiate the admin class to save in the registry
22
- self._registry.append((plugin, options))
23
-
24
-
25
- plugin_dir = HealthCheckPluginDirectory()
File without changes
@@ -1,12 +0,0 @@
1
- from django.apps import AppConfig
2
-
3
- from health_check.plugins import plugin_dir
4
-
5
-
6
- class HealthCheckConfig(AppConfig):
7
- name = "health_check.storage"
8
-
9
- def ready(self):
10
- from .backends import DefaultFileStorageHealthCheck
11
-
12
- plugin_dir.register(DefaultFileStorageHealthCheck)
@@ -1,73 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import dataclasses
4
- import datetime
5
- import uuid
6
-
7
- from django.core.files.base import ContentFile
8
- from django.core.files.storage import storages
9
-
10
- from health_check.backends import HealthCheck
11
- from health_check.deprecation import deprecated
12
- from health_check.exceptions import ServiceUnavailable
13
-
14
-
15
- @dataclasses.dataclass
16
- class StorageHealthCheck(HealthCheck):
17
- """
18
- Check file storage backends by saving, reading, and deleting a test file.
19
-
20
- Args:
21
- alias (str): The alias of the storage backend to check. Defaults to "default".
22
-
23
- """
24
-
25
- alias: str = "default"
26
-
27
- def get_storage(self):
28
- return storages[self.storage_alias if hasattr(self, "storage_alias") else self.alias]
29
-
30
- def get_file_name(self):
31
- return f"health_check_storage_test/test-{uuid.uuid4()}.txt"
32
-
33
- def get_file_content(self):
34
- return f"# generated by health_check.Storage at {datetime.datetime.now().timestamp()}".encode()
35
-
36
- def check_save(self, file_name, file_content):
37
- storage = self.get_storage()
38
- # save the file
39
- file_name = storage.save(file_name, ContentFile(content=file_content))
40
- # read the file and compare
41
- if not storage.exists(file_name):
42
- raise ServiceUnavailable("File does not exist")
43
- with storage.open(file_name) as f:
44
- if not f.read() == file_content:
45
- raise ServiceUnavailable("File content does not match")
46
- return file_name
47
-
48
- def check_delete(self, file_name):
49
- storage = self.get_storage()
50
- # delete the file and make sure it is gone
51
- storage.delete(file_name)
52
- if storage.exists(file_name):
53
- raise ServiceUnavailable("File was not deleted")
54
-
55
- def check_status(self):
56
- try:
57
- # write the file to the storage backend
58
- file_name = self.get_file_name()
59
- file_content = self.get_file_content()
60
- file_name = self.check_save(file_name, file_content)
61
- self.check_delete(file_name)
62
- return True
63
- except ServiceUnavailable as e:
64
- raise e
65
- except Exception as e:
66
- raise ServiceUnavailable("Unknown exception") from e
67
-
68
-
69
- @deprecated(
70
- "`DefaultFileStorageHealthCheck` is deprecated: use `health_check.Storage` instead. Action: remove legacy storage sub-apps from `INSTALLED_APPS` and add `health_check.Storage` to your `HealthCheckView.checks`. See migration guide: https://codingjoe.dev/django-health-check/migrate-to-v4/ (docs/migrate-to-v4.md)."
71
- )
72
- class DefaultFileStorageHealthCheck(StorageHealthCheck):
73
- alias = "default"
health_check/urls.py DELETED
@@ -1,18 +0,0 @@
1
- import warnings
2
-
3
- from django.urls import path
4
-
5
- from health_check.views import MainView
6
-
7
- warnings.warn(
8
- "The `health_check.urls` module is deprecated: it has been replaced by view-based checks. Action: use `health_check.views.MainView` or `HealthCheckView.as_view(checks=...)` in your URLconf. See migration guide: https://codingjoe.dev/django-health-check/migrate-to-v4/ (docs/migrate-to-v4.md).",
9
- DeprecationWarning,
10
- stacklevel=2,
11
- )
12
-
13
- app_name = "health_check"
14
-
15
- urlpatterns = [
16
- path("", MainView.as_view(), name="health_check_home"),
17
- path("<str:subset>/", MainView.as_view(), name="health_check_subset"),
18
- ]