Syncs Pi-hole adlists to Cloudflare Gateway Zero Trust.
The codebase implements a custom retry system in src/requests.py with differentiated handling for different error types:
| Error Type | Status Codes | Retry Behavior | Total Retry Window |
|---|---|---|---|
| Server-side (5xx) | 500-599 | 15 retries with exponential backoff | ~5.5 minutes |
| Rate limit (429) | 429 | Unlimited retries, 2 min initial delay | Continues until success |
| Client errors (4xx) | 400, 403, 404 | 5 retries with exponential backoff | ~31 seconds |
| Network errors | Timeout, connection failures | 5 retries with exponential backoff | ~31 seconds |
HTTPException
├── RateLimitException # 429 - never stops retrying
└── ServerSideException # 5xx - 15 retries before failure
cloudflare_gateway_request()- Core API wrapper with 30s timeout@retry(**retry_config)- Decorator applying retry logic to Cloudflare API calls@rate_limited_request- Decorator enforcing 1 req/s rate limiting
update_list()insrc/cloudflare.pyhas internal retry logic for "item not found in list" errors (400s from removing already-removed domains)- Network timeouts (30s) are separate from retry backoff - failed requests count as one retry attempt
- Exponential backoff uses
max_wait=30seconds for server-side errors
GitHub Actions runs python -m src run daily at 02:00 UTC via .github/workflows/main.yml.