#!/usr/bin/env python3
"""Download/update MaxMind GeoLite2-City database.
Usage:
MAXMIND_LICENSE_KEY=your_key python scripts/download_geoip.py
The free GeoLite2 database requires a license key from MaxMind.
Get one free at: https://dev.maxmind.com/
The database is stored at data/geoip/GeoLite2-City.mmdb
and is mounted into the container at /app/data/geoip/.
"""
import os
import sys
import urllib.request
import urllib.error
DB_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "data", "geoip")
DB_PATH = os.path.join(DB_DIR, "GeoLite2-City.mmdb")
LICENSE_KEY = os.environ.get("MAXMIND_LICENSE_KEY", "")
def download():
if not LICENSE_KEY:
print("ERROR: MAXMIND_LICENSE_KEY not set.")
print("Get a free license key at https://dev.maxmind.com/")
sys.exit(1)
os.makedirs(DB_DIR, exist_ok=True)
url = f"https://download.maxmind.com/app/geoip_download?edition_id=GeoLite2-City&license_key={LICENSE_KEY}&suffix=tar.gz"
print(f"Downloading GeoLite2-City from MaxMind...")
try:
urllib.request.urlretrieve(url, "geolite2.tar.gz")
except urllib.error.HTTPError as e:
print(f"ERROR: MaxMind returned {e.code}: {e.reason}")
print("Check your license key and try again.")
sys.exit(1)
import tarfile
print("Extracting...")
with tarfile.open("geolite2.tar.gz", "r:gz") as tar:
# Find the .mmdb file in the archive (filename varies by version)
members = [m for m in tar.getmembers() if m.name.endswith(".mmdb")]
if not members:
print("ERROR: No .mmdb file found in archive.")
os.remove("geolite2.tar.gz")
sys.exit(1)
tar.extract(members[0], DB_DIR)
# Move to standard name
extracted = os.path.join(DB_DIR, os.path.basename(members[0].name))
if extracted != DB_PATH:
os.replace(extracted, DB_PATH)
os.remove("geolite2.tar.gz")
import subprocess
size = os.path.getsize(DB_PATH)
print(f"Database saved to {DB_PATH} ({size:,} bytes)")
# Verify it's a valid MMDB file
result = subprocess.run(
["python3", "-c", f"import maxminddb; maxminddb.lookup('{DB_PATH}'); print('Verification OK')"],
capture_output=True, text=True, cwd=os.path.dirname(os.path.abspath(__file__))
)
print(result.stdout.strip() or "Verification skipped (maxminddb not available)")
if __name__ == "__main__":
download()