Coverage for conf/settings/link_validation.py: 76%
33 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 06:14 +0000
« prev ^ index » next coverage.py v7.15.2, created at 2026-10-07 06:14 +0000
1import json
2import os
3from collections import defaultdict
4from datetime import timedelta
6from django.core.exceptions import ImproperlyConfigured
8import structlog
9from decouple import config
12logger = structlog.get_logger(__name__)
15LINK_VALIDATION_TIMEOUT_SECONDS = config(
16 "LINK_VALIDATION_TIMEOUT_SECONDS", default=0.8, cast=float
17)
20class LinkValidationCacheExpiryConfiguration(defaultdict):
21 """Link validation cache expiry configuration."""
23 SETTING_PREFIX = "LINK_VALIDATION_CACHE_EXPIRY__"
25 # Cache successful links for a month, and broken links for 120 days.
26 OVERALL_DEFAULT = {"days": 120}
27 STATUS_DEFAULTS = {
28 200: {"days": 30},
29 -1: {"minutes": 30},
30 }
32 def __init__(self):
33 default = self._config("default", default=self.OVERALL_DEFAULT)
34 super().__init__(lambda: default)
36 self.update(
37 {k: self._config(k, default=v) for k, v in self.STATUS_DEFAULTS.items()}
38 )
40 for k, v in os.environ.items():
41 if not k.startswith(self.SETTING_PREFIX) or k.lower().endswith("default"): 41 ↛ 44line 41 didn't jump to line 44 because the condition on line 41 was always true
42 continue
44 try:
45 status = int(k.replace(self.SETTING_PREFIX, ""))
46 except ValueError:
47 raise ImproperlyConfigured(
48 "Invalid link validation cache setting name: "
49 f"{self.SETTING_PREFIX}. Please ensure settings "
50 "are named in the format of "
51 f"'{self.SETTING_PREFIX}<http integer status code>'."
52 )
54 value = self._config(status)
56 self[status] = value
58 def _config(self, key: str | int, default: dict | None = None) -> int | None:
59 try:
60 v = config(
61 f"{self.SETTING_PREFIX}{str(key)}",
62 default=default,
63 # Value should either be a str or dict here
64 cast=lambda x: json.loads(x) if isinstance(x, str) else x,
65 )
66 return int(timedelta(**v).total_seconds())
67 except (json.JSONDecodeError, TypeError):
68 raise ImproperlyConfigured(
69 f"Invalid link validation cache setting. Impossible to parse {key}."
70 )
73# Custom link validation expiration times
74# Overrides can be set via LINK_VALIDATION_CACHE_EXPIRY__<http integer status code>
75# and should be set as kwarg dicts for datetime.timedelta
76# E.g. LINK_VALIDATION_CACHE_EXPIRY__200='{"days": 1}' will set the expiration time
77# for links with HTTP status 200 to 1 day
78LINK_VALIDATION_CACHE_EXPIRY_CONFIGURATION = LinkValidationCacheExpiryConfiguration()