Sign In
Access your IPWhois.net account
No account? Create one
Python Integration
Flask decorator and Django middleware for blocking blacklisted IPs with built-in caching.
5 min setup Flask / Django Cached lookups
Blacklist / Docs / Python
Installation
pip install requests
Core Module
ipwhois_guard.py
import requests from time import time from functools import wraps _cache = {} CACHE_TTL = 3600 # 1 hour MIN_CONFIDENCE = 70 API_URL = "https://bl.ipwhois.net/api" def check_ip(ip, min_confidence=MIN_CONFIDENCE): """Check if an IP is blacklisted. Returns threat data or None.""" now = time() if ip in _cache and now - _cache[ip]["ts"] < CACHE_TTL: return _cache[ip]["data"] try: resp = requests.get( f"{API_URL}/check", params={"ip": ip}, timeout=3 ) data = resp.json() if data.get("listed") and data.get("confidence", 0) >= min_confidence: _cache[ip] = {"data": data, "ts": now} return data else: _cache[ip] = {"data": None, "ts": now} return None except Exception: return None def report_ip(ip, threat_type="brute-force", message=""): """Report a malicious IP to the blacklist.""" try: requests.post( f"{API_URL}/report", data={"ip": ip, "type": threat_type, "message": message}, timeout=5 ) except Exception: pass
Flask Integration
app.py
from flask import Flask, request, abort, jsonify from ipwhois_guard import check_ip app = Flask(__name__) def block_blacklisted(f): """Decorator to block blacklisted IPs.""" @wraps(f) def decorated(*args, **kwargs): ip = request.headers.get("X-Forwarded-For", request.remote_addr) ip = ip.split(",")[0].strip() threat = check_ip(ip) if threat: return jsonify({ "error": "Blocked", "reason": threat.get("threat_type", "blacklisted") }), 403 return f(*args, **kwargs) return decorated @app.route("/login", methods=["POST"]) @block_blacklisted def login(): # Your login logic here return jsonify({"status": "ok"}) @app.route("/api/data") @block_blacklisted def api_data(): return jsonify({"data": "example"})
Django Middleware
middleware/ipwhois.py
from django.http import JsonResponse from ipwhois_guard import check_ip # Paths to protect (prefix match) PROTECTED_PATHS = ["/admin/", "/accounts/login/", "/api/"] class IPWhoisMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): # Only check protected paths if any(request.path.startswith(p) for p in PROTECTED_PATHS): ip = self.get_client_ip(request) threat = check_ip(ip) if threat: return JsonResponse( {"error": "Blocked", "reason": threat.get("threat_type")}, status=403 ) return self.get_response(request) @staticmethod def get_client_ip(request): xff = request.META.get("HTTP_X_FORWARDED_FOR") if xff: return xff.split(",")[0].strip() return request.META.get("REMOTE_ADDR", "")

Add to settings.py:

MIDDLEWARE = [ 'middleware.ipwhois.IPWhoisMiddleware', # ... other middleware ]
Testing
# Test the module directly python3 -c " from ipwhois_guard import check_ip result = check_ip('8.8.8.8') print('Clean IP:' if result is None else 'Blocked:', result) " # Test with Flask flask run & curl -s http://localhost:5000/login -X POST
Troubleshooting
  • requests not installed: Run pip install requests in your virtual environment.
  • SSL errors: Update certifi: pip install --upgrade certifi.
  • Slow responses: The 3-second timeout prevents blocking. Consider using aiohttp for async Flask/Django apps.
  • Memory growth: The dict cache grows unbounded for very high traffic. Use Redis with django.core.cache or Flask-Caching for production.
IPWhois Blacklist — Community-driven IP threat intelligence — ipwhois.net