django-health-check 4.0rc1__py3-none-any.whl → 4.0rc3__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-health-check
3
- Version: 4.0rc1
3
+ Version: 4.0rc3
4
4
  Summary: Monitor the health of your Django app and its connected services.
5
5
  Keywords: django,postgresql
6
6
  Author-email: Kristian Ollegaard <kristian@oellegaard.com>, Johannes Maron <johannes@maron.family>
@@ -1,8 +1,8 @@
1
1
  health_check/__init__.py,sha256=1ADgSDnupPOVTlVpJnjHm9nVGDcjhTjVMO_s9e-NGz0,438
2
- health_check/_version.py,sha256=aT6RyaQ7nKhRVnwCeTgHxtrd9T0i8UdsQNY0JFEplSg,717
2
+ health_check/_version.py,sha256=WQ0-REvimWbQOv0YzR48ShrNHCK3T5uI-X2qdIxGz00,717
3
3
  health_check/base.py,sha256=QvErHU2-iQQOua1_nEfLsSuMQIF6Mn5hz68Y9a1OYQY,2932
4
4
  health_check/checks.py,sha256=xcBkDIF5u3GDRBILXxm6TQMYTPv2hQcrpnmKUFgUIDI,11362
5
- health_check/exceptions.py,sha256=Wd7P3F1ZuqJ8ioAIq4kHzmijsyUGL_PBatmqrQB-3-w,655
5
+ health_check/exceptions.py,sha256=qqxMFMLlYsmrAFoaGepHdzsMmllw3u9UnUtd0NKRgx8,525
6
6
  health_check/views.py,sha256=HCeEr-BcyfSZD9tS6LBXwvZejT2lSOV0OMLSn9e7hkc,10725
7
7
  health_check/contrib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  health_check/contrib/celery.py,sha256=WGqOo3InSooAEQRH1S8BY-NzC1mfRrDo9oTl9BKCxGI,2361
@@ -12,9 +12,9 @@ health_check/contrib/redis.py,sha256=FDYZgZHKw2_Z8hY17pm40QMpHrk0V2mgEPGv3wihT2A
12
12
  health_check/contrib/rss.py,sha256=fjcAjqk_nWZGUbjh_UsY6ENfrVZMBZ70aKf4oG4B6CM,3793
13
13
  health_check/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  health_check/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
- health_check/management/commands/health_check.py,sha256=29VIAGEulKzYkaQbFmw4kyYZR3U6k7IkBjj2qPHVN0A,1579
15
+ health_check/management/commands/health_check.py,sha256=6RY2OB4WoLMIOhgRb8dwzljJDFy676AaAFveiBodn2c,4607
16
16
  health_check/templates/health_check/index.html,sha256=BqWM5l-p8CKoOfZn1hmLF_QTqImTJ9dH3lMrXJjNtT4,4523
17
- django_health_check-4.0rc1.dist-info/licenses/LICENSE,sha256=19Rs8FInCokFQuq03cab_KHwpeyF5pt-lTp7pfJX1iE,1101
18
- django_health_check-4.0rc1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
19
- django_health_check-4.0rc1.dist-info/METADATA,sha256=lvj2mktANDAIomKXyMw16sKqaf5cpCugsm-hXSYIioQ,3695
20
- django_health_check-4.0rc1.dist-info/RECORD,,
17
+ django_health_check-4.0rc3.dist-info/licenses/LICENSE,sha256=19Rs8FInCokFQuq03cab_KHwpeyF5pt-lTp7pfJX1iE,1101
18
+ django_health_check-4.0rc3.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
19
+ django_health_check-4.0rc3.dist-info/METADATA,sha256=aiLihP5MjMJ67-3dhQbP_ggRClCmAq2Z2vxFmlxwZfo,3695
20
+ django_health_check-4.0rc3.dist-info/RECORD,,
health_check/_version.py CHANGED
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '4.0rc1'
32
- __version_tuple__ = version_tuple = (4, 0, 'rc1')
31
+ __version__ = version = '4.0rc3'
32
+ __version_tuple__ = version_tuple = (4, 0, 'rc3')
33
33
 
34
- __commit_id__ = commit_id = 'g9814c8393'
34
+ __commit_id__ = commit_id = 'g1e96d3f90'
@@ -9,12 +9,7 @@ class HealthCheckException(Exception):
9
9
 
10
10
 
11
11
  class ServiceWarning(HealthCheckException):
12
- """
13
- Warning of service misbehavior.
14
-
15
- If the `HealthCheckView.warnings_as_errors` is set to True,
16
- this will be treated as and fail the health check.
17
- """
12
+ """Warning of service misbehavior."""
18
13
 
19
14
  message_type = "Warning"
20
15
 
@@ -1,14 +1,28 @@
1
+ import os
1
2
  import sys
2
3
  import urllib.error
3
4
  import urllib.request
4
5
 
6
+ from django.conf import settings
5
7
  from django.core.management.base import BaseCommand
6
- from django.urls import reverse
8
+ from django.urls import NoReverseMatch, reverse
7
9
 
8
10
 
9
11
  class Command(BaseCommand):
10
12
  help = "Run health checks and exit 0 if everything went well."
11
13
 
14
+ @property
15
+ def default_forwarded_host(self):
16
+ return (
17
+ settings.ALLOWED_HOSTS[0].strip(".")
18
+ if settings.ALLOWED_HOSTS and settings.ALLOWED_HOSTS[0] != "*"
19
+ else None
20
+ )
21
+
22
+ @property
23
+ def default_addrport(self):
24
+ return ":".join([os.getenv("HOST", "127.0.0.1"), os.getenv("PORT", "8000")])
25
+
12
26
  def add_arguments(self, parser):
13
27
  parser.add_argument(
14
28
  "endpoint",
@@ -19,28 +33,92 @@ class Command(BaseCommand):
19
33
  "addrport",
20
34
  nargs="?",
21
35
  type=str,
22
- help="Optional port number, or ipaddr:port (default: localhost:8000)",
23
- default="localhost:8000",
36
+ default=self.default_addrport,
37
+ help=f"Optional port number, or ipaddr:port (default: {self.default_addrport})",
38
+ )
39
+ parser.add_argument(
40
+ "--forwarded-host",
41
+ type=str,
42
+ default=self.default_forwarded_host,
43
+ help=f"Value for X-Forwarded-Host header (default: {self.default_forwarded_host})",
44
+ )
45
+ parser.add_argument(
46
+ "--forwarded-proto",
47
+ type=str,
48
+ choices=["http", "https"],
49
+ default="https",
50
+ help="Value for X-Forwarded-Proto header (default: https)",
51
+ )
52
+ parser.add_argument(
53
+ "--timeout",
54
+ type=int,
55
+ default=5,
56
+ help="Timeout in seconds for the health check request (default: 5 seconds)",
24
57
  )
25
58
 
26
59
  def handle(self, *args, **options):
27
60
  endpoint = options.get("endpoint")
28
- path = reverse(endpoint)
29
- host, sep, port = options.get("addrport").partition(":")
30
- url = f"http://{host}:{port}{path}" if sep else f"http://{host}{path}"
31
- request = urllib.request.Request( # noqa: S310
32
- url, headers={"Accept": "text/plain"}
61
+ try:
62
+ path = reverse(endpoint)
63
+ except NoReverseMatch as e:
64
+ self.stderr.write(
65
+ f"Could not resolve endpoint {endpoint!r}: {e}\n"
66
+ "Please provide a valid URL pattern name for the health check endpoint."
67
+ )
68
+ sys.exit(2)
69
+ addrport = options.get("addrport")
70
+ # Use HTTPS only when SSL redirect is enabled without forwarded headers (direct HTTPS required).
71
+ # Otherwise use HTTP (typical for containers with X-Forwarded-Proto header support).
72
+ proto = (
73
+ "https"
74
+ if settings.SECURE_SSL_REDIRECT and not settings.USE_X_FORWARDED_HOST
75
+ else "http"
33
76
  )
77
+ url = f"{proto}://{addrport}{path}"
78
+
79
+ headers = {"Accept": "text/plain"}
80
+
81
+ # Add X-Forwarded-Host header
82
+ if forwarded_host := options.get("forwarded_host"):
83
+ headers["X-Forwarded-Host"] = forwarded_host
84
+
85
+ # Add X-Forwarded-Proto header
86
+ if forwarded_proto := options.get("forwarded_proto"):
87
+ headers["X-Forwarded-Proto"] = forwarded_proto
88
+
89
+ if options.get("verbosity", 1) >= 2:
90
+ self.stdout.write(
91
+ f"Checking health endpoint at {url!r} with headers: {headers}"
92
+ )
93
+
94
+ request = urllib.request.Request(url, headers=headers) # noqa: S310
34
95
  try:
35
- response = urllib.request.urlopen(request) # noqa: S310
96
+ response = urllib.request.urlopen(request, timeout=options["timeout"]) # noqa: S310
36
97
  except urllib.error.HTTPError as e:
37
- # 500 status codes will raise HTTPError
38
- self.stdout.write(e.read().decode("utf-8"))
39
- sys.exit(1)
98
+ match e.code:
99
+ case 500: # Health check failed
100
+ self.stdout.write(e.read().decode("utf-8"))
101
+ sys.exit(1)
102
+ case 400:
103
+ self.stderr.write(
104
+ f"{url!r} is not reachable: {e.reason}\nPlease check your ALLOWED_HOSTS setting or use the --forwarded-host option."
105
+ )
106
+ sys.exit(2)
107
+ case _:
108
+ self.stderr.write(
109
+ "Unexpected HTTP error "
110
+ f"when trying to reach {url!r}: {e}\n"
111
+ f"You may have selected an invalid endpoint {endpoint!r}"
112
+ f" or another application is running on {addrport!r}."
113
+ )
114
+ sys.exit(2)
40
115
  except urllib.error.URLError as e:
41
116
  self.stderr.write(
42
- f'"{url}" is not reachable: {e.reason}\nPlease check your ALLOWED_HOSTS setting.'
117
+ f"{url!r} is not reachable: {e.reason}\nPlease check your server is running and reachable."
43
118
  )
44
119
  sys.exit(2)
120
+ except TimeoutError as e:
121
+ self.stderr.write(f"Timeout when trying to reach {url!r}: {e}")
122
+ sys.exit(2)
45
123
  else:
46
124
  self.stdout.write(response.read().decode("utf-8"))